tiny slider react 错误 ReferenceError: window is not defined Nextjs13

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

tiny slider react error ReferenceError: window is not defined Nextjs13

问题

I'm using 'Next.js 13' to build a website, and I have a slider of my products on my homepage, which I'm creating using 'tiny-slider-react.' I added 'use client' in the first line of my 'carousel.js' file. However, every time I reload the page, I encounter this error:

  • error node_modules\tiny-slider\dist\tiny-slider.js (5:0) @ eval
  • error ReferenceError: window is not defined

I also can't run 'npm run build' because it gets this error:

ReferenceError: window is not defined

To avoid this error, you should ensure that the code using 'window' or browser-specific features is only executed in a client-side context, like within a 'useEffect' hook with a check for 'typeof window === "object"'. Additionally, make sure that your server-side rendering configuration in Next.js is set up correctly to avoid using 'window' on the server.

英文:

I'm using 'NextJs 13to build a website, in my home I have a slider of my products and I usetiny-slider-react` to create a slider.

I added use client in the first line of my carousel.js file;

carousel.js file code:

"use client";
import TinySlider from "tiny-slider-react";
import CarouselItem from "./carousel-item";
import "tiny-slider/dist/tiny-slider.css";
import { useEffect, useState } from "react";

function Carousel(props) {
  const [mount, setMount] = useState(false);
  const { children } = props;

  useEffect(() => {
    if (typeof window === "object") {
      setMount(true);
    }
  }, [setMount, window]);

  const settings = {
    lazyload: true,
    nav: false,
    mouseDrag: true,
    loop: true,
    items: 1,
    gutter: 20,
    controls: false,
    autoplay: true,
    autoplayHoverPause: true,
    autoplayButtonOutput: false,
    speed: 250,
    autoplayTimeout: 2500,
    responsive: {
      2048: {
        items: 10,
      },
      1920: {
        items: 4,
      },
      1728: {
        items: 4,
      },
      1440: {
        items: 4,
      },
      1280: {
        items: 4,
      },
      1194: {
        items: 4,
      },
      1114: {
        items: 4,
      },
      1180: {
        items: 4,
      },
      1104: {
        items: 4,
      },
      1024: {
        items: 4,
      },
      834: {
        items: 2,
      },
      820: {
        items: 2,
      },
      800: {
        items: 2,
      },
      768: {
        items: 2,
      },
    },
  };

  if (mount) {
    return (
      <TinySlider settings={settings} onInit={() => {}}>
        {props.data.map((item) => (
          <CarouselItem key={item.id} data={item} />
        ))}
      </TinySlider>
    );
  }
  return null;
}

export default Carousel;

but every time I reload the page I get this error:

  • error node_modules\tiny-slider\dist\tiny-slider.js (5:0) @ eval

  • error ReferenceError: window is not defined

  • at webpack_require
    (F:\Projects\nexjs\decoz.next\server\webpack-runtime.js:33:42)
    at webpack_require (F:\Projects\nexjs\decoz.next\server\webpack-runtime.js:33:42)
    at webpack_require (F:\Projects\nexjs\decoz.next\server\webpack-runtime.js:33:42)
    at eval (./components/theme/home/carousel/carousel.js:7:75)

and I can't run 'npm run build` too, it gets this error:

info - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules

  • info Linting and checking the validity of types
  • info Collecting page data
    [ ] - info Generating static pages (0/4)ReferenceError: window is not defined
    at 1107 (F:\Projects\nexjs\decoz.next\server\chunks\738.js:10552:13)
    at webpack_require (F:\Projects\nexjs\decoz.next\server\webpack-runtime.js:25:42)
    at 6088 (F:\Projects\nexjs\decoz.next\server\chunks\738.js:10212:19)
    at webpack_require (F:\Projects\nexjs\decoz.next\server\webpack-runtime.js:25:42)
    at 7086 (F:\Projects\nexjs\decoz.next\server\chunks\738.js:10478:40)
    at webpack_require (F:\Projects\nexjs\decoz.next\server\webpack-runtime.js:25:42)

How to avoid this error?

package.json:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "aos": "^2.3.4",
    "eslint": "8.40.0",
    "eslint-config-next": "13.4.1",
    "next": "13.4.1",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tiny-slider-react": "^0.5.7"
  }
}

答案1

得分: 0

你将window作为你的useEffect钩子的依赖项传递了。首先,这是不必要的。其次,它在Next尝试在服务器上渲染组件时导致错误。

你可以通过将你的效果重写如下来解决此错误。

useEffect(() => {
  setMount(true);
}, []);

更新: 这里的另一个问题是,tiny-slider-react 与SSR不兼容,因为它直接引用了 window 对象。你可以通过动态导入 tiny-slider-react 来解决此错误。

import dynamic from "next/dynamic";
const TinySlider = dynamic(() => import("tiny-slider-react"));
英文:

You are passing window as a dependency of your useEffect hook. First of all, it is unnecessary. Second, it causes your error when Next tries to render your component on the server.

You can resolve this error by rewriting your effect as follows.

useEffect(() => {
  setMount(true);
}, []);

UPDATE: Another issue here is that tiny-slider-react is not compatible with SSR as it's referencing window object directly. You can resolve this error by dynamically importing tiny-slider-react.

import dynamic from "next/dynamic";
const TinySlider = dynamic(() => import("tiny-slider-react"));

答案2

得分: 0

以下是翻译好的部分:

"Hey I had the same issue and managed to resolve with the following additional changes to Igor Danchenko's dynamic import solution.

First is a disabling server-side rendering for the plugin by adding the following parameter to the dynamic import:

const TinySlider = dynamic(() => import("tiny-slider-react"), {
ssr: false,
});

and secondly toggling reactStrictMode: false in next.config.js.

If you leave strict mode set to true then it appears the plugin will fail while in dev environment, but will render correctly when running in prod."

英文:

Hey I had the same issue and managed to resolve with the following additional changes to Igor Danchenko's dynamic import solution.

First is a disabling server-side rendering for the plugin by adding the following parameter to the dynamic import:

const TinySlider = dynamic(() => import("tiny-slider-react"), {
    ssr: false,
});

and secondly toggling reactStrictMode: false in next.config.js.

If you leave strict mode set to true then it appears the plugin will fail while in dev environment, but will render correctly when running in prod.

huangapple
  • 本文由 发表于 2023年5月24日 23:57:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76325409.html
匿名

发表评论

匿名网友

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

确定