Next.js 创建自定义Portal时出现document is not defined错误如何解决?
报错成因
Next.js 默认开启服务端渲染(SSR/SSG),组件代码会先在服务端 Node.js 环境执行一次预渲染,而 document 是浏览器端专属 API,服务端环境不存在该对象。你在 Header.js 中直接调用 document.getElementById("header"),代码执行到服务端阶段时就会触发 document is not defined 报错。
解决方案
可选择以下任意一种方式处理:
- 方案1:在组件内判断执行环境,仅客户端挂载后再渲染Portal
修改Header.js代码如下:
import React, { Fragment, useEffect, useState } from "react"; import ReactDOM from "react-dom"; import NavigationBar from "./NavigationBar"; import classes from "./header.module.css"; const Header = (props) => { const [isClientMounted, setIsClientMounted] = useState(false); // useEffect仅会在客户端执行 useEffect(() => { setIsClientMounted(true); }, []); // 服务端渲染阶段直接返回空,避免调用document if (!isClientMounted) { return null; } return ( <Fragment> {ReactDOM.createPortal( <NavigationBar>{props.children}</NavigationBar>, document.getElementById("header") )} </Fragment> ); }; export default Header;
- 方案2:将Header组件标记为仅客户端渲染
使用Next.js提供的dynamic导入能力,关闭组件的服务端渲染,在引用Header的位置修改导入逻辑:
import dynamic from 'next/dynamic'; // 替换为你实际的Header组件路径,关闭ssr后组件只会在客户端执行 const Header = dynamic(() => import('./Header'), { ssr: false });
内容的提问来源于stack exchange,提问作者Amir Hossein
相关产品推荐
相关产品推荐

