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

Reactjs访问state中存储的axios返回数组数据报错如何解决

问题根因

  • 重渲染死循环问题:如果你直接在组件渲染流程中调用setState存储映射结果,setState会触发组件重渲染,重渲染又会再次执行setState,形成无限循环,就会触发too many re-renders错误。
  • 读取undefined属性报错问题:
    1. 组件首次渲染时,接口还没返回数据,countriesList是空数组,此时通过filter匹配国家会得到空数组,你直接访问border[0].name时,border[0]为undefined,自然会报错。
    2. 你写的长度判断逻辑完全无效:borderCountries是你主动往里面推和props.data长度一致的项,不管有没有匹配到国家,长度永远相等,等于没做判断。
    3. filter是返回符合条件的数组,此处你只需要匹配单个对应国家,用filter反而多套了一层数组,逻辑冗余容易出错。
    4. 你在map中只写了console.log没有返回国家名称,最终返回的数组全是undefined,也没法正常渲染。

修复方案

优先用useMemo缓存计算结果,不需要额外声明state就能避免重复计算,也不会触发死循环;同时增加加载状态判断和匹配容错,避免访问undefined属性。
修正后代码如下:

import axios from "axios";
import { useState, useEffect, useMemo } from "react";

const BorderCountries = (props) => {
  const [countriesList, setCountriesList] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    axios
      .get(`https://restcountries.com/v3.1/all`)
      .then((countries) => {
        setCountriesList(countries.data);
        setIsLoading(false);
      })
      .catch((error) => {
        console.log(`${error}`);
        setIsLoading(false);
      });
  }, []);

  // 用useMemo缓存计算结果,只有依赖项变化时才重新计算
  const borderCountryNames = useMemo(() => {
    // 还在加载或者没有传入边境代码时直接返回空
    if (isLoading || !props.data?.length) return [];
    return props.data.map(code => {
      // 用find直接找匹配的单个国家,不用filter套数组
      const matchCountry = countriesList.find(country => country.cca3 === code);
      // 匹配不到的情况做兜底,避免报错
      return matchCountry ? matchCountry.name.common : code;
    });
  }, [isLoading, countriesList, props.data]);

  return (
    <div>
      <h3>Border Countries:</h3>
      {isLoading ? <span>加载中...</span> : borderCountryNames.join('、')}
    </div>
  );
};

export default BorderCountries;

如果确实需要把结果存在state里,只需要把计算逻辑放到useEffect里,监听countriesList和props.data的变化触发更新即可,不会触发死循环:

// 额外声明state存结果的写法
const [borderNames, setBorderNames] = useState([]);
useEffect(() => {
  if (isLoading || !props.data?.length) return;
  const names = props.data.map(code => {
    const matchCountry = countriesList.find(country => country.cca3 === code);
    return matchCountry ? matchCountry.name.common : code;
  });
  setBorderNames(names);
}, [isLoading, countriesList, props.data]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 05:57:01