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

React中useEffect内API请求函数未执行及map报错问题排查

问题分析与解决方案:API调用无输出+map读取undefined报错

问题原因

1. 控制台未打印「Hello」

组件初始化时location.state可能为undefined,执行fromStation = location.state.fromS直接抛出错误,导致组件渲染中断,useEffect中的trainDetails()完全没机会执行,因此不会打印「Hello」。此外,trainDetails未做错误捕获,若API请求抛出异常也会中断执行,但「Hello」在请求前,核心原因还是location.state的未校验问题。

2. 「Cannot read properties of undefined (reading 'map')」报错

  • trainData初始值设为空字符串"",API请求返回前trainData.data是undefined,直接调用map方法触发错误。
  • 即使请求成功,若返回数据结构不符合预期,trainData.data仍可能为undefined,同样会报错。

解决方案

1. 校验location.state,避免初始化崩溃

读取location.state属性前先做可选链判断,或者直接在组件渲染前校验:

// 方式1:可选链+默认值
const fromStation = location.state?.fromS || '';
const toStation = location.state?.toS || '';

// 方式2:提前校验,不符合则提示
if (!location.state?.fromS || !location.state?.toS) {
  return <div>请选择有效的出发/到达车站</div>;
}

2. 修复trainData初始值与map前的安全校验

  • 将trainData初始值改为包含空数组的对象,确保data属性始终存在:
const [trainData, setTrainData] = useState({ data: [] });
  • 调用map前用可选链判断trainData.data是否存在,同时添加唯一key属性避免React警告:
{trainData.data?.map((train) => {
  return (
    <div className="train-container" key={train.trainNumber}>
      <Box>
        <Card train={train} />
      </Box>
      <div className="btn">
        <Button>Book</Button>
      </div>
    </div>
  );
})}

3. 给异步请求添加错误捕获,修正请求成功判断逻辑

原代码中!response.ok的判断逻辑错误(axios的response.ok在2xx状态码时为true),同时添加try/catch捕获请求异常:

async function trainDetails() {
  setLoading(true);
  console.log("Hello");
  try {
    const options = {
      method: "GET",
      url: "https://irctc1.p.rapidapi.com/api/v3/trainBetweenStations",
      params: {
        fromStationCode: `${fromStation}`,
        toStationCode: `${toStation}`,
        dateOfJourney: "2023-05-20",
      },
      headers: {
        "X-RapidAPI-Key": "{apiKey}",
        "X-RapidAPI-Host": "irctc1.p.rapidapi.com",
      },
    };

    const response = await axios.request(options);
    console.log(response.status);
    // 修正判断逻辑:2xx状态码时为请求成功
    if (response.ok) {
      console.log(response.data.data);
      setTrainData(response.data);
    } else {
      console.log('请求失败,状态码:', response.status);
    }
  } catch (error) {
    console.error('API请求出错:', error);
  } finally {
    setLoading(false);
  }
}

4. 完善useEffect依赖数组

如果出发/到达车站变化时需要重新请求数据,将fromStation和toStation加入依赖,同时判断有效值再执行请求:

useEffect(() => {
  if (fromStation && toStation) {
    trainDetails();
  }
}, [fromStation, toStation]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:35:16