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

React调用足球API遇TypeError:无法读取undefined的'ft'属性求助

解决React中访问未定义比赛比分字段导致的TypeError问题

这个问题在处理API返回的非结构化数据时很常见——当部分比赛数据缺失score字段时,直接链式访问.score.ft就会触发Cannot read property 'ft' of undefined的错误。我们可以通过安全属性访问和逻辑封装来优雅解决,同时实现无数据时显示“暂无信息”的需求。

解决方案思路

  1. 使用可选链操作符(?.):它会在访问嵌套属性前自动检查上层值是否存在,避免直接访问undefined的属性。
  2. 封装工具函数:把比分显示的逻辑抽成独立函数,既让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:06:20