React-NextJS Select组件:动态过滤NHL API有效赛季选项
如何过滤NHL API中无数据的无效赛季?
问题背景
我通过NHL API获取指定球员的赛季数据,已经定义了包含多个赛季的seasonOptions数组,用React Select组件选择赛季并请求数据。现在需要遍历所有赛季选项,过滤掉那些请求后返回req.stats[0].splits.length === 0的无效赛季,只保留有数据的赛季供选择。
解决方案
可以通过以下步骤实现动态过滤有效赛季:
1. 添加状态管理
新增状态存储有效赛季选项、加载状态,并调整选中赛季的初始值:
import { useState, useEffect } from 'react'; // ... const [select, setSelect] = useState(null); const [validSeasonOptions, setValidSeasonOptions] = useState([]); const [isLoadingSeasons, setIsLoadingSeasons] = useState(true);
2. 编写赛季验证函数
创建异步函数遍历所有赛季,逐个请求API验证是否有有效数据,并收集有效赛季:
const validateSeasons = async () => { setIsLoadingSeasons(true); const validSeasons = []; for (const season of seasonOptions) { try { const url = `https://statsapi.web.nhl.com/api/v1/people/${props.playerId}/stats?stats=statsSingleSeason&season=${season.value}`; const response = await fetch(url); const req = await response.json(); // 验证条件:无错误信息且存在有效数据 if (!req.messageNumber && req.stats?.[0]?.splits.length > 0) { validSeasons.push(season); } } catch (error) { console.error(`验证赛季${season.label}失败:`, error); } // 添加延迟避免触发API速率限制 await new Promise(resolve => setTimeout(resolve, 100)); } setValidSeasonOptions(validSeasons); // 默认选中最后一个有效赛季并加载数据 if (validSeasons.length > 0) { setSelect(validSeasons[validSeasons.length - 1]); handlePlayerStats(`https://statsapi.web.nhl.com/api/v1/people/${props.playerId}/stats?stats=statsSingleSeason&season=${validSeasons[validSeasons.length - 1].value}`); } setIsLoadingSeasons(false); };
3. 组件挂载时触发验证
使用useEffect在组件挂载或球员ID变化时,自动执行赛季验证:
useEffect(() => { validateSeasons(); }, [props.playerId]);
4. 更新Select组件
将Select的选项替换为过滤后的有效赛季,并添加加载状态提示:
{isLoadingSeasons ? ( <div>加载有效赛季中...</div> ) : ( <Select id="select" instanceId="select" options={validSeasonOptions} placeholder="选择赛季" autoFocus value={select} onChange={(selected) => { setSelect(selected); handlePlayerStats( `https://statsapi.web.nhl.com/api/v1/people/${props.playerId}/stats?stats=statsSingleSeason&season=${selected.value}` ); }} /> )}
5. 优化数据请求函数
给handlePlayerStats添加可选链操作符,避免访问不存在的属性导致报错:
const handlePlayerStats = async (url) => { try { const response = await fetch(url); const req = await response.json(); console.log(req); if (req.messageNumber) { setFetchedData([]); } else if (req.stats?.[0]?.splits.length > 0) { setFetchedData(req); } else { setFetchedData([]); } } catch (error) { console.log(error); setFetchedData([]); } };
关键说明
- 循环请求时添加100ms延迟,避免触发NHL API的速率限制
- 使用
?.可选链操作符,防止API返回结构异常导致代码崩溃 - 新增加载状态,提升用户等待体验
- 球员ID变化时自动重新验证赛季,确保数据与当前球员匹配
内容的提问来源于stack exchange,提问作者thatnewguy8
相关产品推荐
相关产品推荐

