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

Next.js 13中window is not defined错误及动态导入问题排查

解决Next.js中window未定义及组件渲染报错问题

核心问题分析

你遇到的问题本质是Next.js的SSR/SSG渲染机制导致的:即使组件加了'use client',组件的渲染逻辑仍会在服务器端执行一次(用于hydration),而服务器环境没有window对象,所以直接在渲染函数里访问window.innerHeight就会报错。另外动态导入的错误大概率是组件导出或类型配置的问题。


分步解决方案

1. 正确处理渲染函数中的window依赖

不要在渲染函数中直接访问window,改用useState存储窗口高度,通过useEffect在客户端初始化并监听窗口变化:

'use client'

import { useState, useEffect } from 'react'
import FirstModule from './FirstModule'
import SecondModule from './SecondModule'

export const HorizontalModule = (props: any) => {
  const [windowHeight, setWindowHeight] = useState(0)
  const [scrollPosition, setScrollPosition] = useState(0)

  // 初始化并监听窗口高度变化
  useEffect(() => {
    const updateWindowHeight = () => setWindowHeight(window.innerHeight)
    updateWindowHeight()
    window.addEventListener('resize', updateWindowHeight)
    return () => window.removeEventListener('resize', updateWindowHeight)
  }, [])

  // 监听滚动位置(如果你的scrollPosition是通过滚动事件获取的)
  useEffect(() => {
    const handleScroll = () => setScrollPosition(window.scrollY)
    window.addEventListener('scroll', handleScroll)
    return () => window.removeEventListener('scroll', handleScroll)
  }, [])

  return (
    <>
      {scrollPosition >= 0 && <FirstModule />}
      {scrollPosition >= windowHeight * 2 && <SecondModule />}
    </>
  )
}

这样渲染时用的是windowHeight状态,初始值0和服务器端渲染结果一致,不会触发hydration不匹配的错误,后续在客户端通过useEffect更新为真实的窗口高度。

2. 修复动态导入的错误

如果必须用动态导入(比如组件依赖大量客户端API),确保导出和导入的写法正确:

// 父组件中(如果父组件是服务器组件,这个写法没问题)
import dynamic from 'next/dynamic'

// 简化写法,若组件是命名导出则保留.then,默认导出可直接写import路径
const HorizontalModule = dynamic(() => 
  import('./HorizontalModule/HorizontalModule').then(mod => mod.HorizontalModule),
  {
    ssr: false,
    suspense: true,
    loading: () => <p>Loading...</p>
  }
)

注意:如果你的HorizontalModule是默认导出,直接写import('./path')即可,不用.then(mod => mod.HorizontalModule),之前的"Object is not a function"错误大概率是导出和导入不匹配导致的。

3. 避免hydration错误的额外注意事项

  • 不要在组件顶层直接判断window === undefined,因为服务器端渲染时会返回空片段,客户端渲染时会返回真实内容,导致hydration不匹配。
  • 所有依赖客户端API的状态,初始值要设为服务器端能兼容的值(比如0、''、null等),再通过useEffect在客户端更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:00:09