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

React调用API加载数据时出现多次重复请求问题

React 接口重复调用、控制台累计打印6次日志问题排查&修复

核心原因

  • React 18+ 开发环境默认开启的严格模式(Strict Mode)是首要触发因素。严格模式为了提前暴露不规范的副作用写法,会在开发环境对所有组件执行「挂载→卸载→二次挂载」的双执行流程,直接让组件渲染、副作用执行次数翻倍,这个机制仅在开发环境生效,生产环境不会触发。
  • 自定义Hook的useEffect依赖配置不合规。你写的useGetProducts中useEffect传入了空依赖数组[],但effect内部实际使用了入参API;同时组件中调用Hook时传入的是模板字符串实时拼接的地址`${API}?limit=5&offset=1`,每次组件渲染都会生成新的字符串引用,空依赖写法会导致effect无法正确感知参数变化,配合严格模式的双挂载、状态更新触发的重渲染,日志和请求次数会持续叠加。
  • 重渲染链路叠加计数:组件首次挂载时products初始值为空数组,触发第一次日志打印;effect执行完成后setProducts更新状态,触发第二次渲染打印日志;严格模式下组件卸载重挂载,会完整复现一遍「空值初始渲染→effect拉取数据→状态更新重渲染」的流程,再叠加父组件重渲染、路由初始化带来的挂载动作,很容易累计到6次日志输出。

修复方案

  • 补全useEffect依赖,增加请求清理逻辑避免竞态
    修改useGetProducts的代码,不要用空数组逃避依赖检查,同时增加请求取消逻辑,组件卸载或参数变化时取消未完成的旧请求:
const useGetProducts = (API) => {
  const [products, setProducts] = useState([])

  useEffect(() => {
    const controller = new AbortController();
    const fetchData = async () => {
      try {
        const response = await axios(API, { signal: controller.signal });
        setProducts(response.data)
      } catch (err) {
        // 主动取消的请求不需要抛错
        if (err.name === 'CanceledError') return;
        console.error('产品列表拉取失败:', err);
      }
    }
    fetchData();
    // 清理函数:组件卸载/依赖变化时取消未完成的请求
    return () => controller.abort();
  }, [API]); // 将用到的API参数加入依赖数组

  return products;
}
  • 固定API参数引用,避免无意义的重复触发
    如果请求参数是固定值,直接把拼接好的API地址提到组件外部作为常量;如果参数是动态值,用useMemo缓存拼接结果,避免每次渲染生成新的字符串引用触发effect重跑:
// 固定参数场景:直接提到组件外作为常量
const PRODUCT_LIST_API = `${API}?limit=5&offset=1`;
const ProductList = () => {
  // 动态参数场景用useMemo缓存:
  // const productListApi = useMemo(() => `${API}?limit=${limit}&offset=${offset}`, [API, limit, offset])
  const products = useGetProducts(PRODUCT_LIST_API);
  
  console.log("products: ", products);

  return (
    <section>
      <div>
        {products.map((product) => (
          <ProductItem product={product} key={product.id} />
        ))}
      </div>      
    </section>
  )
}
  • 不要为了避免重复调用关闭严格模式。严格模式的双调用机制只会在开发环境出现,本质是帮你提前排查副作用未清理、内存泄漏类的问题,只要做好请求清理逻辑,开发环境的重复请求不会影响生产环境的实际运行表现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:54:19