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

React中如何正确在循环内调用useFetch Hook实现批量数据请求

报错原因

React 官方明确规定所有 Hook 必须在组件顶层作用域调用,禁止在循环、条件判断、嵌套函数内执行 Hook。你在 for 循环中调用 useFetch 违反了这一规则,因此触发了编译报错。

正确实现方案

你不需要循环调用 useFetch,可以在拿到周期长度后,通过 useEffect 手动发起批量请求,示例代码如下:

import { useState, useEffect } from 'react';

// 原有拉取周期列表的逻辑保持不变
const [period_waterfall, periodLoading, periodError] = useFetch(`/company/${firminfo.code}/periods`);
// 新增状态存储批量拉取的waterfall数据、加载态、错误态
const [waterfallList, setWaterfallList] = useState([]);
const [waterfallLoading, setWaterfallLoading] = useState(false);
const [waterfallError, setWaterfallError] = useState(null);

useEffect(() => {
  // 周期列表未加载完成时跳过执行
  if (!period_waterfall?.periods?.length) return;
  const periodLength = period_waterfall.periods.length;
  setWaterfallLoading(true);

  const fetchAllWaterfall = async () => {
    try {
      // 生成所有请求的Promise数组
      const requestList = Array.from({ length: periodLength }, (_, index) => {
        return fetch(`/company/${slug}/waterfall?colIndexOffset=${index}`).then(res => {
          if (!res.ok) throw new Error(`请求${index}失败`);
          return res.json();
        });
      });
      // 并发执行所有请求
      const resultList = await Promise.all(requestList);
      setWaterfallList(resultList);
    } catch (err) {
      setWaterfallError(err);
    } finally {
      setWaterfallLoading(false);
    }
  };

  fetchAllWaterfall();
}, [period_waterfall, slug]); // 依赖项需完整声明
可选优化点
  • 如果请求数量较多,可将 Promise.all 替换为分批请求逻辑,避免触发浏览器并发请求数限制
  • 若需要支持单个请求失败不中断整体拉取,可以给每个请求单独包一层 catch,返回错误标记而非直接抛出异常
  • 若你的 useFetch 内部支持取消请求,可在 useEffect 的清理函数中添加批量取消请求的逻辑,避免组件卸载后触发状态更新警告

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:06:02