error ReferenceError: document is not defined and cannot read properties of undefined (reading 'style') (NextJS Custom Carousel bug)

huangapple go评论79阅读模式
英文:

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对象不可用,因为它通常只在浏览器中存在。您可以采用以下方法来解决这个问题:

  1. 使用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);
  }, []); // 空数组确保只在组件挂载时执行一次

  // ...其他代码...
};
  1. 检查其他错误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:

error ReferenceError: document is not defined and cannot read properties of undefined (reading 'style') (NextJS Custom Carousel bug)

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'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've attended several workshops in the past, but Saliyab'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'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;

ReferenceError Pic:
error ReferenceError: document is not defined and cannot read properties of undefined (reading 'style') (NextJS Custom Carousel bug)

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.

TypeError pic:
error ReferenceError: document is not defined and cannot read properties of undefined (reading 'style') (NextJS Custom Carousel bug)

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。有几种解决此错误的方法:

  1. 一旦加载完成,可以在useEffect内部访问document
  2. 在访问document之前,检查window是否未定义。

对于第一种方法,您可以使用useEffectcarouselFunction.js转换为自定义钩子,对于第二种方法,在访问document之前在carouselFunction.js中执行检查。

有关更多详细信息,请参阅以下帖子,其中包含这两种方法的详细示例:

https://stackoverflow.com/questions/75408148/referenceerror-document-is-not-defined-inside-next-js-client-component?noredirect=1&lq=1

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:

  1. Access the document inside useEffect once it is loaded
  2. 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/75408148/referenceerror-document-is-not-defined-inside-next-js-client-component?noredirect=1&lq=1

https://stackoverflow.com/questions/60629258/next-js-document-is-not-defined

huangapple
  • 本文由 发表于 2023年5月25日 00:02:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76325451.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定