你的 useEffect 为什么“跑了两遍”?真相在这里

如果你在 React 里写了一个 useEffect,明明只打算执行一次,结果在控制台看见它执行了两次——别担心,你绝对不是唯一的那个。

如果你在 React 里写了一个 useEffect,明明只打算执行一次,结果在控制台看见它执行了两次——别担心,你绝对不是唯一的那个。

你也许问过:

  • “这是个 bug 吗?”
  • “我写法不对?”
  • “React 把什么东西弄坏了?”

好消息是: 这不是 bug,而是刻意为之。 下面把来龙去脉讲清楚,并给出正确的思考方式。

你大概率写的是这段代码

useEffect(() => {
  console.log("Effect ran");
}, []);

你本来预期它只会打印一次,对吧?

可是在开发环境里,你可能看到:

Effect ran
Effect ran

原因:React 的 Strict Mode(严格模式)

从 React 18+ 开始,很多新建项目(如 create-react-app、Next.js 等脚手架)在开发模式会默认启用 StrictMode

StrictMode 只在开发环境下,会把某些生命周期相关逻辑额外再跑一轮——目的,是帮助你尽早发现不安全的副作用(例如未清理的订阅、对外部可变对象的意外修改、遗漏的异步清理等)。

<React.StrictMode>
  <App />
</React.StrictMode>

❗注意:这个“双触发”只发生在开发环境。 一旦打包上线到生产,useEffect 会按预期只跑一次

React 为什么这样做

React 的意图,是让你提前暴露潜在风险,从而在真正上线前就把坑填好。因此,它试图“加压测试”你的副作用代码,以便发现这些问题:

  • 忘记清理订阅或计时器
  • 在渲染阶段引发副作用(应当避免)
  • 重复的拉取请求或多余的状态重置

把它想象成一次“安全演练”:在进入生产之前,先在训练场把问题暴露出来,因此导致你看到“多跑了一次”的表象。

实例:数据请求为什么会被发两次

假设你在 useEffect 中请求数据:

useEffect(() => {
  fetch("/api/data")
    .then(res => res.json())
    .then(setData);
}, []);

在开发环境,效果被“演练”两次,于是会打两次 API。这当然不理想

✅ 应对办法:加一个“只执行一次”的标记(ref)或采用专门的数据请求库。

const hasFetched = useRef(false);

useEffect(() => {
  if (!hasFetched.current) {
    hasFetched.current = true;
    fetch("/api/data")
      .then(res => res.json())
      .then(setData);
  }
}, []);

或者,直接使用 React Query(等数据层库),它们在实践中已经把这类问题处理得相对稳妥。

到底哪些东西会被“触发两次”

在 React 18 的严格模式下,组件初次挂载时,下列内容会被“演练式”调用两次:

  • useEffect
  • useLayoutEffect
  • 类组件的 componentDidMount 与 componentWillUnmount

重要的是要分清:React 并没有让你的应用“双渲染”。 实际流程是:挂载 → 卸载 → 再次挂载,借此验证你的副作用是否可安全重复。

如何确认“这只是开发时的行为”

最直接的办法:跑一遍生产构建。

npm run build
npm start

在生产模式下,你会看到 useEffect只执行一次。 因此,无需惊慌——这不是系统坏掉,而是 React 在帮你练兵

总结

一开始,这个行为确实会让人困惑,甚至会误以为“哪里炸了”。然而,当你理解了 React 的设计初衷之后,你会发现它其实是在帮你避免那些“还没写出来”的 bug。换句话说,虽然看着“麻烦”,但长远看是增益

  • useEffect 在开发环境里因 Strict Mode 会显得“执行两次”;
  • 这属于特性而非缺陷,目的是提前发现副作用问题
  • 生产环境按预期只跑一次,因此上线后行为是正常的。

降低困惑、提升可控性,可以考虑:

  1. 理解严格模式在测试什么,以及为什么要“挂载—卸载—再挂载”;
  2. 在确需“一次性逻辑”的地方,用 标记/ref 做显式防抖
  3. 采用 React Query 等数据层工具,把副作用与缓存、并发、重复请求控制交给库来处理。

AI大模型学习福利

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。


因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

四、AI大模型商业化落地方案

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值