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

使用useEffect()获取数据时频繁发起GET请求的问题求助

解决React useEffect无限发起API请求的问题

问题原因

你当前的代码把products作为useEffect的依赖项,每次调用setProducts更新状态后,products的引用会发生变化,进而重新触发useEffect发起请求,请求完成后又会更新状态,形成无限循环,导致每秒多次发起GET请求。


解决方案

方案1:仅在组件挂载时请求一次

如果你的需求是页面加载时获取一次数据,直接将依赖数组设为空[],这样useEffect只会在组件首次渲染时执行一次:

const [products, setProducts] = useState({ baskets: [] });

useEffect(() => {
  fetch("/api")
    .then((response) => response.json())
    .then((data) => {
      setProducts(data);
    });
}, []); // 空依赖数组,仅组件挂载时执行

方案2:监听API更新的触发条件

如果需要仅在特定场景下(比如外部操作触发API数据更新)发起请求,可以新增一个专门的触发标识作为依赖:

const [products, setProducts] = useState({ baskets: [] });
// 用数值变化作为API更新的触发标识
const [apiUpdateTrigger, setApiUpdateTrigger] = useState(0);

// 当需要更新API数据时,调用这个函数触发请求
const triggerApiRefresh = () => {
  setApiUpdateTrigger(prev => prev + 1);
};

useEffect(() => {
  fetch("/api")
    .then((response) => response.json())
    .then((data) => {
      setProducts(data);
    });
}, [apiUpdateTrigger]); // 仅当触发标识变化时发起请求

额外优化:避免内存泄漏

为了防止组件卸载时仍在处理请求导致内存泄漏,可以添加请求取消逻辑:

const [products, setProducts] = useState({ baskets: [] });

useEffect(() => {
  const controller = new AbortController();
  const signal = controller.signal;

  fetch("/api", { signal })
    .then((response) => response.json())
    .then((data) => {
      setProducts(data);
    })
    .catch((error) => {
      // 忽略取消请求的报错
      if (error.name !== 'AbortError') {
        console.error('API请求失败:', error);
      }
    });

  // 组件卸载时取消未完成的请求
  return () => controller.abort();
}, []);

内容的提问来源于stack exchange,提问作者Mustafa Mengütay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:24:54