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

为何useEffect会触发两次?React useEffect执行异常问询

为什么第二个useEffect会触发两次?

你的代码中第二个useEffect触发两次,主要有两种常见原因,对应不同场景:

原因1:初始依赖值触发执行

第二个useEffect的依赖是listVisaoGeral,组件初始渲染时,listVisaoGeral的初始值是[],此时React会执行这个useEffect一次。当第一个useEffect完成数据请求并调用setListVisaoGeral更新state后,listVisaoGeral从空数组变为接口返回的新数组,依赖项发生变化,触发第二次执行。

这种情况是React的正常行为,两次执行分别对应:

  • 组件挂载时的初始state
  • state更新后的新值

原因2:React 18 Strict Mode(开发环境)

如果你的项目开启了Strict Mode(Create React App、Vite等脚手架默认开启),React在开发环境下会模拟组件的卸载和重新挂载,刻意重复执行useEffect、state初始化等逻辑,目的是帮你检测未正确清理的副作用(比如未取消的请求、未清除的定时器)。

这会导致:

  1. 第一个空依赖的useEffect会执行两次,若请求没有缓存,会触发两次接口调用,进而两次更新state,导致第二个useEffect多一次执行;
  2. 即使请求有缓存,state只更新一次,Strict Mode也会让依赖state变化的useEffect执行两次。

解决方案

1. 跳过初始空数组的执行

如果你不需要在初始state(空数组)时执行第二个useEffect,可以添加判断过滤:

useEffect(() => {
  // 跳过初始空数组的情况
  if (listVisaoGeral.length === 0) return;
  console.log("Second");
}, [listVisaoGeral]);

2. 为请求添加清理逻辑(应对Strict Mode)

为了避免Strict Mode下重复请求的问题,给axios请求添加取消逻辑,确保组件卸载时能终止未完成的请求:

const [listVisaoGeral, setListVisaoGeral] = useState([]);

useEffect(() => {
  const abortController = new AbortController();
  console.log("First");
  
  async function getVisaoGeral() {
    try {
      const response = await axiosInstance.get("....", {
        signal: abortController.signal
      });
      setListVisaoGeral(response.data);
    } catch (error) {
      // 忽略取消请求的错误
      if (error.name !== "AbortError") {
        console.log(error);
        Alert.alert(
          "Erro",
          "Não foi possível consultar a lista de recursos. Por favor, tente novamente."
        );
      }
    }
  }

  getVisaoGeral();
  // 组件卸载时取消请求
  return () => abortController.abort();
}, []);

useEffect(() => {
  console.log("Second");
}, [listVisaoGeral]);

3. 临时关闭Strict Mode(仅调试用)

如果只是想验证是否是Strict Mode导致的问题,可以暂时移除项目入口文件(如index.js)中的<StrictMode>标签。注意:生产环境下Strict Mode会自动失效,不建议长期关闭,它能帮你提前发现潜在问题。


内容的提问来源于stack exchange,提问作者Thiago Costa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 11:36:15