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

使用fetch和map获取复杂JSON中指定字段值的问题

无法访问复杂JSON嵌套字段的解决方案

问题重现

尝试从嵌套JSON中读取字段(如match.teams.home)时,出现Cannot read properties of undefined (reading 'home')错误,相关JSON结构和代码如下:

目标JSON结构

{"get": "fixtures",
"parameters": {
    "date": "2024-01-17"
},
"errors": [],
"results": 218,
"paging": {
    "current": 1,
    "total": 1
},
"response": [
    {
        "fixture": {
            "id": 1156472,
            "referee": null,
            "timezone": "UTC",
            "date": "2024-01-17T00:00:00+00:00",
            "timestamp": 1705449600,
            "periods": {
                "first": null,
                "second": null
            },
            "venue": {
                "id": null,
                "name": "TBC",
                "city": "TBC"
            },
            "status": {
                "long": "Time to be defined",
                "short": "TBD",
                "elapsed": null
            }
        },
        "league": {
            "id": 667,
            "name": "Friendlies Clubs",
            "country": "World",
            "logo": "https://media.api-sports.io/football/leagues/667.png",
            "flag": null,
            "season": 2024,
            "round": "Club Friendlies 3"
        },
        "teams": {
            "home": {
                "id": 675,
                "name": "Vasas",
                "logo": "https://media.api-sports.io/football/teams/675.png",
                "winner": null
            },
            "away": {
                "id": 646,
                "name": "Levski Sofia",
                "logo": "https://media.api-sports.io/football/teams/646.png",
                "winner": null
            }
        },
        "goals": {
            "home": null,
            "away": null
        },
        "score": {
            "halftime": {
                "home": null,
                "away": null
            },
            "fulltime": {
                "home": null,
                "away": null
            },
            "extratime": {
                "home": null,
                "away": null
            },
            "penalty": {
                "home": null,
                "away": null
            }
        }
     }
]}

你的代码

let url = "http://localhost:8000/home/";

const [matches, setMatches] = useState([{}]);

const matchData = async () => {
  const res = await fetch(url);
    const d = await res.json();
  
    return setMatches(d.response);
}

useEffect(() => {
    matchData();
}, [{}]);

解决步骤

1. 修正初始状态

初始状态设为[{}]会导致组件首次渲染时,map遍历到空对象,访问teams时直接返回undefined,进而引发读取home的错误。将初始状态改为空数组:

const [matches, setMatches] = useState([]);

2. 修复useEffect依赖

[{}]作为依赖时,每次渲染都会生成新的空对象,导致useEffect无限触发请求。改为空数组,确保仅在组件挂载时执行一次:

useEffect(() => {
    matchData();
}, []);

3. 处理异步加载的空值情况

数据加载完成前,matches是空数组,需通过条件渲染或可选链操作符避免访问未定义属性:

方式一:条件渲染

{matches.length > 0 ? (
  matches.map(match => (
    <div key={match.fixture.id}>
      {match.teams.home.name} vs {match.teams.away.name}
      <p>比赛时间:{match.fixture.date}</p>
    </div>
  ))
) : (
  <div>加载中...</div>
)}

方式二:可选链操作符(推荐)

通过?.自动处理未定义的中间属性,避免报错:

matches.map(match => (
  <div key={match.fixture?.id}>
    {match.teams?.home?.name} vs {match.teams?.away?.name}
    <p>比赛时间:{match.fixture?.date}</p>
  </div>
))

4. 增加请求错误处理

防止请求失败或返回数据结构异常导致的报错,在异步函数中添加try/catch:

const matchData = async () => {
  try {
    const res = await fetch(url);
    if (!res.ok) throw new Error(`请求失败:${res.status}`);
    const d = await res.json();
    // 确保即使response不存在,也设置为空数组
    setMatches(d.response || []);
  } catch (err) {
    console.error('数据获取失败:', err);
    setMatches([]);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:05:10