React18未启用React.StrictMode时useEffect仍双挂载问题咨询
问题产生原因
React 18 版本中useEffect在挂载阶段执行两次是严格模式下的专属检测逻辑,用于提前暴露副作用未正确清理导致的潜在bug,该行为仅在开发环境生效,生产环境构建后会自动移除。未手动书写<React.StrictMode>包裹却出现该问题,均为隐式开启严格模式导致,常见触发场景如下:
- 构建工具的React生态插件默认注入严格模式:非create-react-app的工程方案(比如Vite、自定义Webpack配置)对应的React编译插件,很多版本默认会在应用根节点外层自动包裹
<React.StrictMode>,不需要业务代码手动书写。 - React DevTools全局开关强制开启:浏览器安装的React开发者工具扩展提供了全局强制开启严格模式的配置项,开关开启后会无视页面代码配置,对所有打开的React应用生效。
- 入口渲染逻辑残留配置:部分开发者升级React 18时,从旧版本拷贝的入口代码中可能残留未注意到的StrictMode包裹,或是第三方渲染封装工具默认加入了StrictMode包裹逻辑。
排查与解决方法
- 第一步:确认组件树是否真的处于严格模式
在应用根组件顶层加入如下打印代码,判断严格模式的实际生效状态:
如果输出值为import React from 'react' // 根组件内执行 console.log('严格模式状态:', React.useContext(React.StrictMode))true,说明组件树确实被StrictMode包裹,继续后续排查;如果为false,无需额外调整配置,双执行现象不会出现在生产环境。 - 第二步:关闭构建工具默认注入的严格模式
如果使用Vite构建,修改@vitejs/plugin-react的插件配置,显式关闭严格模式:
如果使用自定义Webpack工程,检查// vite.config.js import react from '@vitejs/plugin-react' export default { plugins: [ react({ strictMode: false // 关闭默认注入的严格模式 }) ] }react-refresh-webpack-plugin等React开发态插件的配置项,关闭强制开启严格模式的相关开关。 - 第三步:检查React DevTools配置
打开浏览器开发者工具的React面板,进入设置页,找到全局严格模式开关,将其调整为关闭状态,避免全局配置覆盖页面代码逻辑。 - 第四步:核对入口渲染代码
确认应用入口的渲染逻辑没有显式包裹StrictMode,React 18标准非严格模式的入口写法如下:import { createRoot } from 'react-dom/client' import App from './App' const rootEle = document.getElementById('root') const root = createRoot(rootEle) root.render(<App />)
补充提示:如果你的useEffect在双执行时出现逻辑异常,优先检查副作用对应的清理函数(即useEffect回调中return的函数)是否正确编写。该开发态双执行逻辑的设计目的就是提前暴露缺失清理逻辑的副作用问题,强行关闭检测反而可能遗漏线上隐患。
内容的提问来源于stack exchange,提问作者TMLS_123
相关产品推荐
相关产品推荐

