为何React Strict Mode未对非纯组件函数发出警告?
React Strict Mode 为何没检测到我的非纯组件?
首先得明确:Strict Mode 不会直接弹出「你写了非纯函数」的警告,它的核心逻辑是在开发环境下重复执行组件的渲染函数、副作用钩子(如 useEffect)等关键代码,让非纯逻辑的副作用暴露出来——毕竟纯函数重复执行应该产生一致的结果,而非纯函数会因为重复执行导致状态、全局变量或输出出现异常。
看你的代码,问题出在你没注意到 Strict Mode 已经在起作用了:
- 当用
<StrictMode>包裹<App />后,开发环境下App的渲染函数会执行两次,bar会被两次加上10 + Math.random(),最终bar的值会比你预期的大很多; - 每个
Foo组件的渲染函数也会执行两次,bar会被额外加两次Math.random(),而且每次渲染时hmm += Math.random()生成的结果也不一样,这会导致组件输出的内容在两次渲染中不一致(可能出现页面闪烁,或者控制台日志重复打印IN APP、IN Foo)。
Strict Mode 就是通过这种方式,让你察觉到「我的组件重复执行后结果不对」,从而发现自己写了非纯逻辑——它不会替你判断「这是非纯函数」,而是把问题暴露在你面前。
再说说 Strict Mode 的核心作用:
- 重复执行渲染函数、useEffect、useLayoutEffect,暴露非纯逻辑和意外副作用;
- 检测不安全的生命周期(比如 componentWillMount);
- 标记过时的 ref 用法(比如使用 React.createRef 以外的方式创建 ref);
- 检测可能导致内存泄漏的清理逻辑问题。
你的测试代码里,全局变量 bar 在渲染中被修改,属于典型的非纯操作——Strict Mode 已经通过重复执行渲染函数让 bar 的值异常了,只是你没把这个异常和 Strict Mode 的作用关联起来。
附你的测试代码:
let bar = 1; function Foo({ hmm }) { console.log("IN Foo"); bar += Math.random(); hmm += Math.random(); return ( <div> hmm is {hmm}, bar is {bar} </div> ); } function App() { console.log("IN APP"); bar += 10 + Math.random(); return ( <> <div>hi {bar}</div> <Foo hmm={123} /> <Foo hmm={456} /> </> ); } export default App;
内容的提问来源于stack exchange,提问作者Stefanie Gauss
相关产品推荐
相关产品推荐

