StrictMode 下为什么看到多次渲染或重复请求?

先理解原理和示例,再练习完整口述与追问。

开发期 StrictMode 可额外调用渲染相关逻辑,并对适用的 Effect 执行额外 setup / cleanup 检查,以暴露不纯与清理缺陷。具体行为与版本及启用位置有关,不是生产环境固定重复请求两次。

StrictMode 的开发检查会额外执行某些渲染、Effect 建立清理或 ref 回调流程,以暴露不纯渲染与清理不完整。它模拟的是开发中需要能够安全重试或重新挂载的关系,不应据此断言生产也固定执行两次。具体检查还受 React 版本和 StrictMode 放置范围影响。

若 Effect 首次连接后未返回断开函数,开发检查中重新建立会留下多个连接;补齐 cleanup 后应能经历建立 → 清理 → 再建立,最后只保留当前连接。请求如果已到服务端,客户端清理不保证撤销,因此真正的写操作还要依赖事件处理与服务端幂等协议。

用一个全局 hasRun 开关跳过第二次,可能掩盖真实资源泄漏并破坏多个实例。修复副作用契约,再解释开发检查与生产行为区别。

StrictMode 在开发环境额外检查渲染纯度,并在适用情况下执行额外的 Effect setup、cleanup、setup,帮助发现清理缺失。这不是生产必然请求两次。正确处理通常是让订阅有对称清理,让请求可取消或忽略过期结果,并把用户主动提交放在事件处理函数而非挂载副作用中。

面试官可能继续问追问与完整解答展开收起

为什么单纯用 ref 阻止第二次执行可能掩盖清理问题?订阅和非幂等请求分别怎么设计?

只用 hasRun ref 阻止第二次 setup,可能让清理后没有重新建立连接,掩盖真正的生命周期错误。订阅要成对订阅和取消;创建订单等非幂等操作需要由用户动作触发并由服务端做幂等保障,不能依赖关闭 StrictMode。