Next.js调用自定义React hook出现ReferenceError: window is not defined报错
问题根因
Next.js 内置服务端渲染(SSR)、静态站点生成(SSG)能力,这两类渲染阶段代码运行在 Node.js 环境,不存在浏览器端的 window 全局对象。
你自定义的 useWindowDimensions hook 直接在 useState 初始化参数中调用了访问 window 的 getWindowDimensions 方法,服务端渲染执行到该逻辑时就会抛出 ReferenceError: window is not defined 错误。之前运行正常大概率是当时用到该 hook 的页面走的是纯客户端渲染,后续页面调整后该 hook 被服务端渲染逻辑命中,就出现了随机报错的情况。
修复方案
修改 useWindowDimensions.js 的初始化逻辑,仅在客户端挂载后(即 useEffect 执行阶段)才访问 window 获取尺寸,初始化阶段给兜底默认值即可,修改后代码如下:
import { useState, useEffect } from 'react'; function getWindowDimensions() { const { innerWidth: width, innerHeight: height } = window; return { width, height, }; } export default function useWindowDimensions() { // 初始化给兜底默认值,不要直接调用访问window的方法 const [windowDimensions, setWindowDimensions] = useState({ width: undefined, height: undefined }); useEffect(() => { // 组件挂载到客户端后再获取真实窗口尺寸 setWindowDimensions(getWindowDimensions()); function handleResize() { setWindowDimensions(getWindowDimensions()); } window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return windowDimensions; }
如果业务逻辑需要避免使用初始的 undefined 值,可以在调用该 hook 的组件中加判断逻辑,比如:
const Footer = () => { const { height, width } = useWindowDimensions(); // 尺寸未获取到(服务端渲染阶段)时可以返回占位结构,或者直接返回null if (!width || !height) return null; // 后续业务逻辑 ... }
如果该组件仅需要在客户端渲染,也可以通过 Next.js 的 dynamic 导入关闭组件的服务端渲染能力:
import dynamic from 'next/dynamic'; const Footer = dynamic(() => import('./Footer'), { ssr: false });
内容的提问来源于stack exchange,提问作者ricemilk
相关产品推荐
相关产品推荐

