英文:
error ReferenceError: document is not defined and cannot read properties of undefined (reading 'style') (NextJS Custom Carousel bug)
问题
在NextJS中,您遇到了一个问题,即在carouselFunction.js
文件中出现了ReferenceError: document is not defined
错误。这是因为在Node.js环境中(在服务器端渲染时),document
对象不可用,因为它通常只在浏览器中存在。您可以采用以下方法来解决这个问题:
- 使用
useEffect
钩子:在Carousel.tsx
组件中使用useEffect
钩子来确保只在客户端渲染时执行carouselFunction.js
。这将确保只有在浏览器中才能访问document
对象。例如:
import React, { useEffect } from "react";
import { changeSlides } from "../Constants/Carousel_Function/carouselFunction.js";
// ...其他代码...
const SaliyabCarousel = () => {
useEffect(() => {
// 在客户端渲染时执行carouselFunction.js
changeSlides(0);
}, []); // 空数组确保只在组件挂载时执行一次
// ...其他代码...
};
- 检查其他错误:
TypeError: Cannot read properties of undefined (reading 'style')
错误可能是由于carouselFunction.js
中的ReferenceError
引发的。一旦您修复了ReferenceError
,可能会解决这个错误。
请尝试这些建议,看看是否可以解决您的问题。希望这些信息能帮助您完成自定义轮播组件的任务。
英文:
I created a custom carousel component that displays text testimonies. This custom carousel is made from scratch which uses a custom script functionality (carouselFunction.js
) for its arrow navigations to traverse to each text testimony displayed. The carousel looks exactly like this:
I have an issue in regards to my custom carousel in NextJS. I get a ReferenceError: document is not defined
within my carouselFunction.js
file (a JS file for the carousel functionality), and I am not sure why it raises that error since I'm only getting the class name "textimony" of the div of my custom carousel component (Carousel.tsx
), and assign that class name to slides variable, which is going to be used within carouselFunction.js
.
source code of carouselFunction.js
:
let slideIndex = 0;
showSlides(slideIndex);
export function changeSlides(n) {
showSlides((slideIndex += n));
}
export function showSlides(n) {
let i;
let slides = document.getElementsByClassName("textimony");
n > slides.length - 1
? (slideIndex = 1)
: n < 0
? (slideIndex = slides.length - 1)
: null;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex].style.display = "flex";
}
source code of Carousel.tsx
:
"use client";
import React from "react";
import Image from "next/image";
import "/app/globals.css";
import Script from "next/script";
import { changeSlides } from "../Constants/Carousel_Function/carouselFunction.js";
import leftArrow from "../resources/Shape Elements/left-arrow.webp";
import rightArrow from "../resources/Shape Elements/right-arrow.webp";
const SaliyabCarousel = () => {
return (
<div>
<div className="textimony">
<a className="left-arrow" onClick={() => changeSlides(-1)}>
<Image src="" width="107" height="104" alt="left arrow pic" />
</a>
<q>
Saliyab&apos;s workshop was a game-changer for me. The insights and
practical advice I gained from the experts in the field helped me to
take my skills to the next level and make a real impact in my work. I
highly recommend it!
</q>
<a className="right-arrow" onClick={() => changeSlides(1)}>
<Image
className="right-arrow"
src={rightArrow}
width="106"
height="104"
alt="right arrow pic"
/>
</a>
</div>
<div className="textimony">
<a className="left-arrow" onClick={() => changeSlides(-1)}>
<Image
src={leftArrow}
width="107"
height="104"
alt="left arrow pic"
/>
</a>
<q>
I&apos;ve attended several workshops in the past, but Saliyab&apos;s
was by far the most informative and engaging. The speakers were
knowledgeable and approachable, and I left feeling motivated and
inspired to pursue new opportunities in the tech industry.
</q>
<a className="right-arrow" onClick={() => changeSlides(1)}>
<Image
className="right-arrow"
src={rightArrow}
width="106"
height="104"
alt="right arrow pic"
/>
</a>
</div>
<div className="textimony">
<a className="left-arrow" onClick={() => changeSlides(-1)}>
<Image
src={leftArrow}
width="107"
height="104"
alt="left arrow pic"
/>
</a>
<q>
The Saliyab workshop provided me with a wealth of new information and
resources that I could immediately apply to my work. I appreciated the
hands-on approach and the chance to network with other professionals
in the field.
</q>
<a className="right-arrow" onClick={() => changeSlides(1)}>
<Image
className="right-arrow"
src={rightArrow}
width="106"
height="104"
alt="right arrow pic"
/>
</a>
</div>
<div className="textimony">
<a className="left-arrow" onClick={() => changeSlides(-1)}>
<Image
src={leftArrow}
width="107"
height="104"
alt="left arrow pic"
/>
</a>
<q>
As a beginner in the tech industry, I was a bit intimidated to attend
the Saliyab workshop. But I&apos;m so glad I did! The workshop was
tailored to all skill levels and I left with a much deeper
understanding of the field and its possibilities.
</q>
<a className="right-arrow" onClick={() => changeSlides(1)}>
<Image
className="right-arrow"
src={rightArrow}
width="106"
height="104"
alt="right arrow pic"
/>
</a>
</div>
<Script src="../Constants/Carousel_Function/carouselFunction.js" />
</div>
);
};
export default SaliyabCarousel;
Not only that, but I also got a TypeError: Cannot read properties of undefined (reading 'style')
, which is I think due to the ReferenceError
above.
I already called the Script
of the carouselFunction.js
on my layout page but the error still persists.
source code of layout.tsx
:
import { Inter } from "next/font/google";
import Script from "next/script";
const inter = Inter({ subsets: ["latin"] });
export const metadata = {
title: "Saliyab Website",
description: "Saliyab Website using NextJS",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<meta charSet="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin="anonymous"
/>
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap"
rel="stylesheet"
/>
<Script src="../Constants/Carousel_Function/carouselFunction.js" />
<body className={inter.className}>{children}</body>
</html>
);
}
I am still learning the ropes of NextJS and it would be of great help to acquire guides and feedbacks in creating my custom carousel in NextJS. I am aware of the existing carousels from component libraries such as Material UI, etc. But I just really wanted to try creating a customized version of mine.
Your responses would indeed help me a lot in finishing this task of mine. Thank you!
答案1
得分: 1
客户端组件在服务器上预渲染,因此它们无法访问document
。有几种解决此错误的方法:
- 一旦加载完成,可以在
useEffect
内部访问document
。 - 在访问
document
之前,检查window
是否未定义。
对于第一种方法,您可以使用useEffect
将carouselFunction.js
转换为自定义钩子,对于第二种方法,在访问document
之前在carouselFunction.js
中执行检查。
有关更多详细信息,请参阅以下帖子,其中包含这两种方法的详细示例:
https://stackoverflow.com/questions/60629258/next-js-document-is-not-defined
英文:
Client components pre-render on the server, so they don't have access to the document
. There are several ways to resolve this error:
- Access the document inside
useEffect
once it is loaded - Check if window is undefined before accessing the document.
For the first method, you could convert carouselFunction.js to a custom hook using useEffect or for the second method, perform the check in carouselFunction.js before accessing the document.
For more details, see these posts, which contain extensive examples of both methods:
https://stackoverflow.com/questions/60629258/next-js-document-is-not-defined
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论