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

Next.js客户端组件报错ReferenceError: document is not defined的解决方法

解决Next.js 13.1.6中Portal组件"document is not defined"错误

问题原因

即使给组件标记了"use client",在Next.js 13.1.6的App Router模式下,客户端组件仍会参与服务器端的初始渲染流程。此时浏览器环境还未初始化,document对象不存在,直接访问document.body就会抛出ReferenceError。

解决方案

方法1:使用useEffect确保客户端挂载后再创建Portal

useEffect钩子只会在客户端执行,通过它标记组件已在客户端挂载,再渲染Portal:

"use client"

import type { ReactPortal } from "react"
import { createPortal } from "react-dom"
import { useEffect, useState } from "react"

interface PortalProps {
  children: React.ReactNode
}

export function Portal(props: PortalProps): ReactPortal | null {
  const [isClientMounted, setIsClientMounted] = useState(false)

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

  // 客户端未挂载时返回null,避免服务器端访问document
  if (!isClientMounted) {
    return null
  }

  return createPortal(props.children, document.body)
}

方法2:直接判断document是否存在

通过检查document的类型,避免在服务器端执行时访问它:

"use client"

import type { ReactPortal } from "react"
import { createPortal } from "react-dom"

interface PortalProps {
  children: React.ReactNode
}

export function Portal(props: PortalProps): ReactPortal | null {
  // 服务器端环境下document不存在,返回null
  if (typeof document === "undefined") {
    return null
  }
  
  return createPortal(props.children, document.body)
}

两种方法都能避免服务器端渲染阶段访问document,解决报错问题。优先推荐方法1,因为它更贴合React的生命周期,确保组件在客户端完全挂载后再渲染Portal内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:00:28