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

App组件中ComponentDidMount被调用两次的问题求助

顶层App组件的componentDidMount被调用两次的问题解决

我的顶层App组件的componentDidMount生命周期钩子被调用了两次,已经精简代码排查,排除了缺少key导致重渲染的常见原因,但问题依然存在。

相关代码

index.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App global={{baseUrl: "http://localhost", port: 54887}} />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
reportWebVitals();

App.tsx

import React from 'react'
import CurrentItems, { CurrentItemsProps } from './CurrentItems';
import Navigation, { NavigationProps } from './Navigation';
import { CombinedNavigationProps } from './Navigation';
import './App.css';
import { GlobalProps } from './GlobalProps';

interface AppProps extends GlobalProps {}

interface AppState {
  navigation: NavigationProps;
}

class App extends React.Component<AppProps, AppState> {
  constructor(props: AppProps){
    super(props);
    //this.onSelectedViewChange = this.onSelectedViewChange.bind(this);
  }

  componentDidMount(){
    console.log("app did mount");
  }

  onSelectedViewChange(view: string) {
  }

  render(){
    if(this.state === undefined || this.state === null){
      return (<div>Loading...</div>);
    } else {
      return (
        <div>
          Loaded.
        </div>
      );
    }
  }
}

export default App;

控制台输出

控制台输出截图

问题原因与解决

这是React 18严格模式的预期行为。在React 18的<React.StrictMode>下,为了帮助开发者检测组件中存在的副作用问题,React会故意重复调用以下方法:

  • 类组件的constructor、componentDidMount、componentWillUnmount
  • 函数组件的useState、useMemo、useEffect等钩子的初始化函数

解决方式

  1. 临时规避:如果只是想消除两次调用的现象,可以移除index.tsx中的<React.StrictMode>包裹,修改后的root.render代码如下:
root.render(
  <App global={{baseUrl: "http://localhost", port: 54887}} />
);
  1. 推荐做法:保留严格模式,检查componentDidMount中的逻辑是否能承受重复执行(比如避免重复发起网络请求、重复订阅事件等)。可以通过添加状态标记来防止重复执行,例如在类组件中增加一个isMounted状态:
componentDidMount(){
  if (!this.state?.isMounted) {
    console.log("app did mount");
    this.setState({ isMounted: true });
    // 在这里执行你的初始化逻辑
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:00:19