部署至Vercel时出现ReferenceError: window is not defined,本地无此问题
问题分析与修复方案
问题原因
你的代码在初始化useState时直接访问了window.innerWidth和window.innerHeight,而Vercel部署时默认会执行服务器端渲染(SSR)。服务器环境中不存在浏览器的window对象,因此这段代码在服务器执行时会抛出ReferenceError: window is not defined。本地开发通常是纯客户端渲染(CSR),所以不会触发这个错误。
修复方案
核心思路是确保仅在客户端环境中访问window对象,以下是两种可行的修复方式:
方案一:初始化时添加环境判断
在useState初始化时,通过typeof window !== 'undefined'判断当前是否为客户端环境,给服务器端设置一个默认占位值:
export function WindowContextProvider({ children }: WindowContextProviderProps): JSX.Element { const [windowSize, setWindowSize] = useState<WindowSize>({ // 服务器端用默认值,客户端用真实窗口尺寸 width: typeof window !== 'undefined' ? window.innerWidth : 1200, height: typeof window !== 'undefined' ? window.innerHeight : 800, }); useEffect(() => { const handleResize = (): void => setWindowSize({ width: window.innerWidth, height: window.innerHeight, }); window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, []); const value: WindowContext = { ...windowSize, isMobile: windowSize.width < 500, }; return <WindowContext.Provider value={value}>{children}</WindowContext.Provider>; }
方案二:在useEffect中初始化尺寸
useEffect的回调函数只会在客户端执行,因此可以把初始尺寸的设置放在这里,彻底避免服务器端访问window:
export function WindowContextProvider({ children }: WindowContextProviderProps): JSX.Element { const [windowSize, setWindowSize] = useState<WindowSize>({ width: 0, height: 0, }); useEffect(() => { // 首次加载时先更新一次窗口尺寸 const updateWindowSize = () => { setWindowSize({ width: window.innerWidth, height: window.innerHeight, }); }; updateWindowSize(); window.addEventListener("resize", updateWindowSize); return () => window.removeEventListener("resize", updateWindowSize); }, []); // 处理初始值为0的情况,避免isMobile判断异常 const value: WindowContext = { ...windowSize, isMobile: windowSize.width > 0 ? windowSize.width < 500 : false, }; return <WindowContext.Provider value={value}>{children}</WindowContext.Provider>; }
注意事项
- 方案一的默认值可以根据页面布局自定义,能减少客户端渲染时的布局跳动;
- 方案二更严谨,但初始状态下
windowSize为{width:0, height:0},需要额外处理isMobile的判断逻辑,防止出现错误状态。
内容的提问来源于stack exchange,提问作者Mintee
相关产品推荐
相关产品推荐

