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

React 18中createRoot引发多次渲染/执行的解决办法

React 18 多次渲染的原因与解决方法

导致多次执行的核心因素

  • React 18 StrictMode 开发环境特性:React 18 在开发模式下,StrictMode 会主动重复调用组件的 render 方法、生命周期函数(如 useEffect、useLayoutEffect)以及状态更新逻辑,目的是提前检测代码中存在的未清理副作用、重复初始化等潜在问题。生产环境下该特性不会生效,不会出现重复渲染。
  • 根实例重复创建(当前代码隐含风险):你的代码中每次调用 renderApp 都会重新执行 createRoot(root),虽然当前只调用了一次 renderApp,但如果后续有逻辑触发重复调用,会导致根实例重复创建,进而引发重复渲染。

让代码仅执行一次的解决方案

方案1:临时移除 StrictMode(开发环境用)

如果只是想在开发阶段看到单次渲染效果,可以暂时去掉 React.StrictMode 的包裹:

const renderApp = () => {
  createRoot(root).render(
    <Provider store={store}>
      <App />
    </Provider>
  );
};

注意:生产环境建议保留 StrictMode,它能帮助你提前发现代码中的隐患。

方案2:确保根实例仅创建一次

将 createRoot 的调用移到 renderApp 函数外部,保证根实例唯一,即使后续多次调用 renderApp,也只是复用同一个根实例进行渲染:

const root = document.getElementById("root");
const rootInstance = createRoot(root); // 仅创建一次根实例

const renderApp = () => {
  rootInstance.render(
    <React.StrictMode>
      <Provider store={store}>
        <App />
      </Provider>
    </React.StrictMode>
  );
};

renderApp();

方案3:适配 StrictMode 行为(推荐)

既然 StrictMode 的重复执行是为了检测副作用,最佳方案是调整组件代码,让逻辑兼容重复执行:

  • 确保副作用逻辑放在 useEffect 中,并正确实现清理函数;
  • 使用 useRef 标记初始化状态,避免重复执行初始化逻辑:
// App 组件内的示例处理
import { useRef, useEffect } from 'react';

function App() {
  const hasInitialized = useRef(false);

  useEffect(() => {
    if (!hasInitialized.current) {
      // 这里放置仅需执行一次的初始化逻辑
      console.log('初始化仅执行一次');
      hasInitialized.current = true;
    }
  }, []);

  return <div>你的组件内容</div>;
}

这种方式既能保留 StrictMode 的检测能力,又能保证核心逻辑只执行一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:32:49