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

React同构应用报错:document is not defined 及渲染问题求助

同构React应用:解决ReferenceError: document is not defined及渲染异常问题

问题根源

你的服务端渲染报错核心原因是:服务端执行renderToString时,App组件内部嵌套了仅适用于客户端的BrowserRouter。BrowserRouter依赖浏览器环境的document对象处理路由逻辑,而Node.js服务端不存在该对象,直接触发ReferenceError。

虽然你在client.js里做了环境判断,但服务端渲染阶段已经会执行App组件内的BrowserRouter代码,这部分判断覆盖不到。

修复步骤

1. 重构App组件,抽离Router逻辑

修改src/components/App.jsx,移除内部的BrowserRouter,只保留路由配置:

import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Home from './Home';
import Archive from './Archive';

const App = () => (
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/archive" element={<Archive />} />
  </Routes>
);

export default App;

2. 在客户端入口包裹BrowserRouter

更新src/client.js,用BrowserRouter包裹App组件(仅在客户端执行):

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './components/App';

if (typeof window !== 'undefined') {
  const root = document.getElementById('root');
  if (root) {
    ReactDOM.createRoot(root).render(
      <BrowserRouter>
        <App />
      </BrowserRouter>
    );
  }
}

3. 确认服务端的StaticRouter配置

你的server.js中已经正确使用StaticRouter包裹App,保持现有逻辑即可:

const appString = renderToString(
  <StaticRouter location={req.url} context={context}>
    <App />
  </StaticRouter>
);

4. 检查页面组件的环境兼容性

如果Home或Archive组件中有直接访问window/document的代码(比如获取窗口尺寸、操作DOM),需要用useEffect延迟执行(useEffect仅在客户端渲染时触发):

// 错误示例(服务端会报错)
const Home = () => {
  const width = window.innerWidth;
  return <div>窗口宽度:{width}</div>;
};

// 正确写法
import { useEffect, useState } from 'react';

const Home = () => {
  const [width, setWidth] = useState(0);

  useEffect(() => {
    setWidth(window.innerWidth);
  }, []);

  return <div>窗口宽度:{width}</div>;
};

验证修复

重新执行npm start,服务端渲染时会使用StaticRouter处理路由(不依赖浏览器环境),客户端 hydration 时用BrowserRouter接管,即可解决document is not defined错误和渲染异常问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:25:04