从Create React App迁移NextJS后遇document和window未定义错误
问题原因及解决办法
你的问题核心是NextJS的渲染机制和Create React App(CRA)不一样:
- CRA是纯客户端渲染,所有代码都在浏览器环境执行,
document、window这些浏览器专属对象天然存在; - NextJS默认是服务端渲染(SSR)或静态生成(SSG),这部分代码会在Node.js环境运行,而Node里根本没有
document、window,所以直接访问就会报错。
具体解决方案
1. 在工具函数里添加环境判断
给你的工具函数加上检查,确保只有在浏览器环境下才访问document/window:
修改setReferrer:
const setReferrer = () => { // 先判断document是否存在(即当前在浏览器环境) if (typeof document !== 'undefined') { const referrer = document.referrer; // 你的后续逻辑 } };
修改setResolution:
const setResolution = () => { // 先判断window是否存在 if (typeof window !== 'undefined') { const resolution = `${window.screen.width * window.devicePixelRatio}x${window.screen.height * window.devicePixelRatio}`; // 你的后续逻辑 } };
2. 在React组件中延迟调用(推荐)
如果这些工具函数是在组件里调用的,把调用逻辑放到useEffect钩子中——useEffect里的代码只会在客户端渲染完成后执行,天然避开服务端环境:
import { useEffect } from 'react'; import { setReferrer, setResolution } from '@/lib/utils'; function YourPage() { useEffect(() => { // 这里的代码只会在浏览器端执行 setReferrer(); setResolution(); }, []); return <div>页面内容</div>; } export default YourPage;
额外提示
如果某个组件完全依赖浏览器API,还可以用NextJS的动态导入,强制组件只在客户端渲染:
import dynamic from 'next/dynamic'; // 禁用服务端渲染,组件只会在浏览器加载 const ClientOnlyComponent = dynamic(() => import('../components/ClientOnly'), { ssr: false, });
内容的提问来源于stack exchange,提问作者dokgu
相关产品推荐
相关产品推荐

