You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js SSR环境下自定义React Hook报window is not defined问题求解

错误根因

你的错误出在服务端渲染阶段执行了调用window的逻辑:Next.js SSR 运行在 Node 环境,不存在window对象,你原代码中useState初始化时直接调用了getWindowDimensions(),服务端渲染执行到这一步就会抛出window未定义的错误。


修复后的自定义Hook代码

useWindowDimensions.tsx修改如下:

import { useState, useEffect } from 'react'

function getWindowDimensions() {
    const { innerWidth: width, innerHeight: height } = window
    return {
        width,
        height,
    }
}

export default function useWindowDimensions() {
    // 初始化给服务端可正常运行的默认值,不要直接调用getWindowDimensions
    const [windowDimensions, setWindowDimensions] = useState({
        width: 0,
        height: 0
    })

    useEffect(() => {
        // 仅在客户端挂载后执行,获取真实窗口尺寸
        setWindowDimensions(getWindowDimensions())

        function handleResize() {
            setWindowDimensions(getWindowDimensions())
        }

        window.addEventListener('resize', handleResize)
        return () => window.removeEventListener('resize', handleResize)
    }, [])

    return windowDimensions
}

业务代码适配说明

如果不想在客户端挂载前触发错误的尺寸计算,可以加一层客户端挂载判断,避免服务端渲染阶段计算出不符合预期的结果:

const { height, width } = useWindowDimensions()
const [isClient, setIsClient] = useState(false)

useEffect(() => {
  setIsClient(true)
}, [])

const dimensions = () => {
  // 服务端渲染阶段直接返回默认值
  if (!isClient) return 0
  if (width > 1900) return width * 0.4
  if (width > 1000) return width * 0.3
  if (width > 800) return width * 0.2
  return width * 0.1
}

如果担心页面初始加载有尺寸闪烁,可以在isClient为false时渲染骨架屏/占位内容,等客户端挂载完成后再渲染真实内容即可。


内容的提问来源于stack exchange,提问作者elmgren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 01:36:05