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

为何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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:53:13