React组件为何出现挂载、卸载后再次重挂载的异常问题
React组件首次挂载后立刻触发卸载的原因说明
你观察到的组件挂载后随即卸载、再次挂载触发更新的行为,不是代码逻辑异常,是React 18+版本开发环境严格模式的默认设计行为。
核心机制说明
React 18 对开发环境下的严格模式(StrictMode)新增了重复挂载检测逻辑:
- 所有首次挂载的组件,会被自动执行一次「挂载 → 卸载 → 重新挂载」的完整流程
- 该设计的目的是提前暴露不符合React规范的代码问题,比如副作用未清理、内存泄漏、生命周期逻辑写错等问题,避免这些bug流到生产环境
- 该逻辑仅在开发环境、且入口文件开启
React.StrictMode包裹时生效,生产环境构建后不会触发,完全不影响线上运行逻辑
对应你代码的日志解释
你代码中的useEffect执行顺序和日志输出,完全符合严格模式的执行规则:
- 组件第一次挂载:
- 执行空依赖的useEffect回调,打印
Cp Mounted - 执行无依赖的更新useEffect回调,打印
Cp Updated - 执行依赖
counter的useEffect回调,打印Change counter
- 执行空依赖的useEffect回调,打印
- React自动触发模拟卸载:
- 执行空依赖useEffect返回的清理函数,打印
Cp UnMounted
- 执行空依赖useEffect返回的清理函数,打印
- 组件第二次正式挂载:
- 再次执行所有useEffect的回调,依次打印三个挂载相关日志
你之前学习类组件生命周期时遇到的相同现象,也是同一个机制导致的:类组件的componentDidMount、componentWillUnmount生命周期,在React 18严格模式下同样会遵循这个重复执行的检测逻辑。
验证与注意事项
- 你可以打开项目入口文件(通常是
main.jsx/index.js),会看到根组件被<React.StrictMode>标签包裹,移除该包裹后开发环境就不会出现重复挂载卸载的日志 - 不建议为了消除这类日志关闭严格模式:该检测机制可以帮你提前发现很多隐性bug,比如useEffect中绑定的事件监听、定时器未在清理函数中清除的问题,在严格模式的重复执行下会立刻暴露,大幅降低线上出问题的概率。
另外你贴出的子组件代码存在一处语法错误:第三个监听counter的useEffect中,console.log('Change 'counter')写法不符合JS语法,正确写法应为console.log('Change counter'),如果要输出counter变量值可以用模板字符串 console.log(`Change ${counter}`)。
内容的提问来源于stack exchange,提问作者M.F
相关产品推荐
相关产品推荐

