修复Next.js中window is not defined方法详解

 更新时间:2022年12月13日 09:28:45   作者:Jovie  
这篇文章主要为大家介绍了修复Next.js中window is not defined方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

这个问题与Next.js的服务器端渲染有关。Next.js默认会尝试为您的网站使用SSR。这意味着,由于我们是在服务器上而不是在浏览器中,所以 "窗口 "对象并不存在。解决这个问题的方法是强迫Next.js在浏览器中运行你的代码,我将解释如何做到这一点。

使用useEffect钩子

useEffect钩子总是在浏览器中运行,所以我们可以用它来确保我们的代码只能从那里运行。关于钩子的快速入门知识,请查看这篇文章。

下面是一个简单应用的示例代码,它将用户最后一次访问网站的时间存储在本地存储中。如果你不熟悉在React或Next.js中使用localStorage,可以看看我们这里的这个教程,它使用了类似的方法。这个方法是相同的,但有一个小的区别,那就是你可以在vanilla React组件的主体中使用localStorage,因为默认没有SSR:

function updateLastSeen() {
    const lastSeen = window.localStorage.getItem('last-seen') ?? new Date();
    window.localStorage.setItem('last-seen', new Date().toString());
    return lastSeen;
}
function WindowPage() {
    const lastSeen = updateLastSeen();
    return <div>Last Seen: {lastSeen}</div>;
}

运行这个,我们得到这个你可能熟悉的错误:

为了解决这个问题,让我们引入一个自定义的钩子,它涉及一个 useEffect。

function useLastSeen() {
    const [lastSeen, setLastSeen] = useState(null);
    const retrieved = useRef(false); //To get around strict mode running the hook twice
    useEffect(() => {
        if (retrieved.current) return;
        retrieved.current = true;
        setLastSeen(updateLastSeen());
    }, []);
    return lastSeen;
}

我已经把我们的逻辑移到了一个自定义的钩子上,只是为了保持代码的简洁。现在随着我们代码的改变,代码将只在钩子运行时运行,也就是在客户端。

然后我们可以将我们的组件更新为。

function WindowPage() {
    const lastSeen = useLastSeen();
    return (
        <div>
            Last Seen: {lastSeen}
        </div>
    );
}

这段代码更简洁,而且由于 useEffect里面的钩子只在客户端运行,我们的错误就消失了

检查窗口是否被定义

另一种方法是在我们运行代码之前简单地检查窗口对象是否被定义。如果代码在服务器上运行,由于我们不在浏览器中,窗口对象就不存在。

我们不能使用与之前相同的例子,因为这种方法有一个关键的区别。因为我们没有等待组件的渲染,任何对页面HTML的差异都会导致服务器端渲染的页面版本与客户端不同,我们会在Next.js中得到一个错误。

在这个例子中,我们将为窗口对象添加一个事件监听器,以跟踪页面上的点击和它们的位置。

const isBrowser = () => typeof window !== 'undefined'; //The approach recommended by Next.js
function WindowPage() {
    const [lastClick, setLastClick] = useState('');
    if (isBrowser()) { //Only add the event listener client-side
        window.addEventListener('click', (e) =>
            setLastClick(`${e.pageX}, ${e.pageY}`)
        );
    }
    return (
        <div className="m-auto rounded bg-violet-600 p-10 font-bold text-white shadow">
            Click at: {lastClick}
        </div>
    );
}

正如我们所看到的,代码并没有在服务器上运行,所以Next.js现在很高兴了

希望这两种方法中的一种能帮助解决你的问题。我推荐第一种方法,因为它涵盖了大多数情况,而且你不必处理Next.js发现渲染不匹配的可能性。

以上就是修复Next.js中window is not defined方法详解的详细内容,更多关于Next.js window is not defined的资料请关注脚本之家其它相关文章!

相关文章

  • React hook 'useState' is called conditionally报错解决

    React hook 'useState' is calle

    这篇文章主要为大家介绍了React hook 'useState' is called conditionally报错解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • react hooks实现防抖节流的方法小结

    react hooks实现防抖节流的方法小结

    这篇文章主要介绍了react hooks实现防抖节流的几种方法,文中通过代码示例给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-04-04
  • react中使用css的7中方式(最全总结)

    react中使用css的7中方式(最全总结)

    这篇文章主要介绍了react中使用css的7中方式(最全总结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • react写一个select组件的实现代码

    react写一个select组件的实现代码

    这篇文章主要介绍了react写一个select组件的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • React中使用async validator进行表单验证的实例代码

    React中使用async validator进行表单验证的实例代码

    react上进行表单验证是很繁琐的,在这里使用async-validator处理起来就变的很方便了,接下来通过本文给大家介绍React中使用async validator进行表单验证的方法,需要的朋友可以参考下
    2018-08-08
  • React tsx生成随机验证码

    React tsx生成随机验证码

    这篇文章主要为大家详细介绍了React tsx生成随机验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • react中的forwardRef 和memo的区别解析

    react中的forwardRef 和memo的区别解析

    forwardRef和memo是React中用于性能优化和组件复用的两个高阶函数,本文给大家介绍react中的forwardRef 和memo的区别及适用场景,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • react-native动态切换tab组件的方法

    react-native动态切换tab组件的方法

    在APP中免不了要使用tab组件,有的是tab切换,也有的是tab分类切换.这篇文章主要介绍了react-native动态切换tab组件的方法,非常具有实用价值,需要的朋友可以参考下
    2018-07-07
  • React项目中报错:Parsing error: The keyword 'import' is reservedeslint的问题及解决方法

    React项目中报错:Parsing error: The keyword &a

    ESLint 默认使用的是 ES5 语法,如果你想使用 ES6 或者更新的语法,你需要在 ESLint 的配置文件如:.eslintrc.js等中设置 parserOptions,这篇文章主要介绍了React项目中报错:Parsing error: The keyword 'import' is reservedeslint的问题及解决方法,需要的朋友可以参考下
    2023-12-12
  • React Native时间转换格式工具类分享

    React Native时间转换格式工具类分享

    这篇文章主要为大家分享了React Native时间转换格式工具类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10

最新评论