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

React Hooks项目中足球比赛数据首次渲染为空问题求助

解决React Hooks首次渲染过滤比赛数据为空的问题

问题场景

在项目中获取足球比赛数据,按matchday(比赛日)过滤时,首次渲染始终得到空数组;切换标签页返回后才能正常渲染数据。调整useEffect依赖后又触发无限循环。

原代码问题分析

核心问题1:state更新异步导致过滤失效

在getMatches函数中,调用setMatchDay(data.matches[0].season.currentMatchday)后,立即用matchday state过滤数据——但React的state更新是异步的,此时matchday还是初始的空数组,所以过滤条件matchday === match.matchday永远不成立,返回空数组。

核心问题2:useEffect依赖错误导致无限循环

原useEffect依赖matches,而getMatches中会调用setMatches更新这个state,触发useEffect再次执行getMatches,形成无限循环。

切换标签页生效的原因

切换标签页后组件重新渲染,此时matchday已经是上一次请求后更新的值,再次调用getMatches时过滤逻辑使用了正确的matchday,所以能得到结果,但这是依赖缓存的巧合,不是正确逻辑。

修复方案

1. 直接使用API返回的原始值过滤,不依赖异步更新的state

不需要等待matchday state更新,直接用API返回的currentMatchday值做过滤,确保逻辑同步执行。

2. 修正useEffect依赖项

仅在selectedLeague变化时触发请求,因为比赛数据是基于选中的联赛,避免无效请求和循环。

3. 修正loading状态逻辑

在请求开始时设置loading为true,请求结束(成功/失败)后设为false,保证状态准确。

修改后的代码

修正后的getMatches函数

const getMatches = async () => {
  setLoading(true); // 请求开始时开启加载状态
  try {
    const response = await axios.get(`${FOOTBALL_API_URL}/${selectedLeague}/matches`, {
      headers: { 'X-Auth-Token': `${FOOTBALL_API_TOKEN}` }
    });
    const data = response.data;

    // 直接取API返回的当前比赛日,不依赖state
    const currentMatchday = data.matches[0].season.currentMatchday;
    setMatchDay(currentMatchday); // 同步更新state供其他地方使用

    // 用当前获取到的比赛日过滤数据
    const filteredMatches = data.matches.filter(match => match.matchday === currentMatchday);
    console.log('filtered array', filteredMatches);
    setMatches(filteredMatches);
  } catch (error) {
    console.error('获取比赛数据失败:', error);
    // 可添加错误提示逻辑,比如setMatches([])
  } finally {
    setLoading(false); // 请求结束后关闭加载状态
  }
};

修正后的useEffect

React.useEffect(() => {
  // 确保选中联赛有值时才发起请求,避免无效调用
  if (selectedLeague) {
    getMatches();
  }
}, [selectedLeague]); // 仅当选中联赛变化时重新请求数据

额外提示

  • 若data.matches可能为空,需要添加判断避免data.matches[0]报错,比如:
    if (!data.matches || data.matches.length === 0) {
      setMatches([]);
      return;
    }
    
  • state初始值建议更贴合数据类型:matchday是单个数值,初始值设为0而非空数组;LeagueName如果是字符串,初始值设为''而非空数组,避免类型混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:57:19