Nextjs window is not defined 错误

3,467 阅读1分钟

问题

在 Next 中直接使用 window/document 会报 ReferenceError: window is not defined

原因

原因其实也比较简单,由于 nextjs 是服务端渲染,它会预渲染页面后生成 HTML,然后再将其发送给客户端,因此在渲染时无法识别 window/document 浏览器的对象方法。

解决方法

1. 使用 useEffect

这个方案是依赖于 useEffect 在进行服务器端渲染时不运行 useEffet,window 将在挂载时触发,在 useEffect 中的语句意味着服务器永远不会执行它,客户端将在挂载后才执行它(document 同理)。

    useEffect(() =,{
      console.log(window.location)
      window.addEventListener('scroll', function() {
        console.log('srcoll')
      })
    },[])

2. 检查 window

这个方法比较简单粗暴,直接判断 window 是否存在再执行对应代码(document 同理)

const callback = () => {
  if (typeof window !== 'undefined') {
    console.log('window:', window);
  }
};

3. 动态加载组件

使用动态导入和 srr: false 选项加载组件。这样,您的组件甚至不会在服务器端呈现

// components/Scroll.js

function onScroll() {
  console.log('scroll!');
}

window.addEventListener('scroll', onScroll);

export default function Scroll() {
  return null;
}
// pages/index.js

import dynamic from 'next/dynamic';

const Scroll = dynamic(
  () => {
    return import('../components/Scroll');
  },
  { ssr: false },
);