React调用足球API遇TypeError:无法读取undefined的'ft'属性求助
解决React中访问未定义比赛比分字段导致的TypeError问题
这个问题在处理API返回的非结构化数据时很常见——当部分比赛数据缺失score字段时,直接链式访问.score.ft就会触发Cannot read property 'ft' of undefined的错误。我们可以通过安全属性访问和逻辑封装来优雅解决,同时实现无数据时显示“暂无信息”的需求。
解决方案思路
- 使用可选链操作符(?.):它会在访问嵌套属性前自动检查上层值是否存在,避免直接访问
undefined的属性。 - 封装工具函数:把比分显示的逻辑抽成独立函数,既让JSX结构更整洁,也方便后续维护(比如扩展显示半场比分、加时比分等)。
修改后的完整代码
import React, { useEffect, useState } from "react"; import axios from 'axios'; // 封装处理单场比赛比分的工具函数 const getMatchScore = (match) => { // 检查score、ft是否存在,且ft是包含至少两个元素的数组 if (match.score?.ft && Array.isArray(match.score.ft) && match.score.ft.length >= 2) { return `${match.score.ft[0]} - ${match.score.ft[1]}`; } // 任何条件不满足时返回默认文本 return '暂无信息'; } export default function Eredmeny() { const [data, setData] = useState([]); const [index, setIndex] = useState(0); useEffect(() => { const load = async () => { const {data: { matches } } = await axios( "https://raw.githubusercontent.com/openfootball/football.json/master/2020-21/en.1.json" ); setData(matches); } load() }, []) const prev = () => { if( index >= 10){ setIndex(index - 10); } } const next = () => { if( index <= data.length-11){ setIndex(index + 10); } } if (data.length <= 0) { return "Loading..." } return( <div> <h1> <button onClick={prev}>Previous</button> {data[index].round} <button onClick={next}>Next</button> </h1> <h3> <p>{data[index].team1} - {data[index].team2}</p> {getMatchScore(data[index])} <p>{data[index+1].team1} - {data[index+1].team2}</p> {getMatchScore(data[index+1])} <p>{data[index+2].team1} - {data[index+2].team2}</p> {getMatchScore(data[index+2])} <p>{data[index+3].team1} - {data[index+3].team2}</p> {getMatchScore(data[index+3])} <p>{data[index+4].team1} - {data[index+4].team2}</p> {getMatchScore(data[index+4])} <p>{data[index+5].team1} - {data[index+5].team2}</p> {getMatchScore(data[index+5])} <p>{data[index+6].team1} - {data[index+6].team2}</p> {getMatchScore(data[index+6])} <p>{data[index+7].team1} - {data[index+7].team2}</p> {getMatchScore(data[index+7])} <p>{data[index+8].team1} - {data[index+8].team2}</p> {getMatchScore(data[index+8])} <p>{data[index+9].team1} - {data[index+9].team2}</p> {getMatchScore(data[index+9])} </h3> </div> ); }
关键细节说明
- 可选链操作符
?.:比如match.score?.ft,如果match.score是undefined或null,表达式会直接返回undefined,不会继续访问.ft,从根源避免报错。 - 工具函数
getMatchScore:集中处理比分逻辑,不仅检查score和ft是否存在,还验证ft是符合要求的数组(确保有两个比分元素),这样即使API返回的ft格式异常,也能友好显示默认文本。 - 代码复用:原来重复的比分访问逻辑被替换成函数调用,后续如果要修改比分显示规则(比如显示半场比分),只需要修改这一个函数即可。
内容的提问来源于stack exchange,提问作者kurucza
相关产品推荐
相关产品推荐

