React中切换日期时自动更新足球比分API数据的实现方案
足球实时比分模板日期切换数据更新问题解决思路
我用React开发了足球实时比分展示模板,实现了日期切换导航组件,参考BBC足球比分赛程页。目前遇到问题:切换日期时无法自动从API获取对应日期的赛事数据并更新页面内容。以下是相关组件代码、API返回示例及当前数据获取逻辑,寻求解决思路:
一、LiveScore主组件代码
const LiveScore = () => { const {direction} = useThemeProvider(); const [selectedDay, setSelectedDay] = useState(parseInt(dayjs().format('DD'))); return ( <Spring className="card d-flex flex-column"> <div className="card_header d-flex flex-column g-10" style={{paddingBottom: 20}}> <div className="d-flex justify-content-between align-items-center"> <h3>{dayjs().format('MMMM')} matches</h3> </div> <Navigator active={selectedDay} setActive={setSelectedDay}/> </div> <div className="card_header d-flex flex-column g-10"> <LeagueHeader img={english_premier} title="English Premier League" subtitle="Regular Championship" /> </div> <div className={styles.grid}> <div className={styles.scroll}> <ScrollContainer height={0}> <div className={`${styles.scroll_track} ${styles[direction]} track d-flex flex-column g-20`}> { matches.map((match, index) => ( <MatchMonthCard match={match} index={index} key={index}/> )) } </div> </ScrollContainer> </div> <div className={`${styles.card} ${styles[direction]}`}> <MatchMonthCard match={matches[2]} variant="extended"/> </div> </div> </Spring> ) }
二、日期切换导航组件(Navigator)代码
const Navigator = ({active, setActive}) => { const {theme, direction} = useThemeProvider(); const [swiper, setSwiper] = useState(null); useEffect(() => { if (swiper) { swiper.slideToLoop(parseInt(active) - 1); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [swiper, active]); useEffect(() => { if (swiper) { swiper.changeLanguageDirection(direction); swiper.update(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [swiper, direction]); return ( <div className={`${styles.navigator} ${theme === 'light' ? styles.light : styles.dark}`}> <Swiper className="h-100" slidesPerView="auto" spaceBetween={10} centeredSlides={true} onSwiper={setSwiper} loop initialSlide={+active - 1} > { getMonthDays().map((day, index) => ( <SwiperSlide className={styles.slide} key={index}> <div className={classNames(`${styles.navigator_item} ${styles[direction]}`, {[styles.active]: active === parseInt(day.date)})} onClick={() => setActive(parseInt(day.date))}> <h4 className={styles.day}>111111</h4> <span className="label h6">{day.weekday}</span> </div> </SwiperSlide> )) } </Swiper> </div> ) }
三、API返回示例
{ "get": "fixtures", "parameters": { "season": "2023", "date": "2024-01-15" }, "errors": [], "results": 67, "paging": { "current": 1, "total": 1 }, "response": [ { "fixture": { "id": 1150218, "referee": "Ismael Rosario Lopez Penuelas, Mexico", "timezone": "UTC", "date": "2024-01-15T00:00:00+00:00", "timestamp": 1705276800, "periods": { "first": 1705276800, "second": 1705280400 }, "venue": { "id": 1080, "name": "Estadio Victoria", "city": "Aguascalientes" }, "status": { "long": "Match Finished", "short": "FT", "elapsed": 90 } }, "league": { "id": 262, "name": "Liga MX", "country": "Mexico", "logo": "https://media.api-sports.io/football/leagues/262.png", "flag": "https://media.api-sports.io/flags/mx.svg", "season": 2023, "round": "Clausura - 1" }, "teams": { "home": { "id": 2288, "name": "Necaxa", "logo": "https://media.api-sports.io/football/teams/2288.png", "winner": true }, "away": { "id": 2283, "name": "Atlas", "logo": "https://media.api-sports.io/football/teams/2283.png", "winner": false } }, "goals": { "home": 2, "away": 1 }, "score": { "halftime": { "home": 0, "away": 1 }, "fulltime": { "home": 2, "away": 1 }, "extratime": { "home": null, "away": null }, "penalty": { "home": null, "away": null } } } ] }
四、当前数据获取逻辑
const [matches, setMatches] = useState([]); const url = "http://127.0.0.1:8000/${date}"; const [data, setData] = useState([{}]); const matchData = async () => { const res = await fetch(url); const d = await res.json(); return setData(d.response); } useEffect(() => { matchData(); }, [{}]);
问题分析与解决步骤
核心问题点
- URL使用双引号导致模板字符串
${date}无法解析,请求地址错误 - useEffect依赖数组用
[{}],既会重复触发请求,又没关联selectedDay状态,切换日期时不会触发新请求 - 获取到的
data未同步到页面渲染用的matches状态
具体修复方案
修复URL模板字符串:把双引号改成反引号,同时用dayjs将
selectedDay格式化为API需要的YYYY-MM-DD格式const formattedDate = dayjs().date(selectedDay).format('YYYY-MM-DD'); const url = `http://127.0.0.1:8000/${formattedDate}`;修正useEffect依赖:将依赖数组改为
[selectedDay],确保日期切换时自动触发数据请求useEffect(() => { matchData(); }, [selectedDay]);同步数据到渲染状态:去掉冗余的
data状态,直接将API返回的赛事数据赋值给matchesconst [matches, setMatches] = useState([]); const matchData = async () => { const formattedDate = dayjs().date(selectedDay).format('YYYY-MM-DD'); const url = `http://127.0.0.1:8000/${formattedDate}`; const res = await fetch(url); const d = await res.json(); setMatches(d.response); }可选优化:添加加载状态和错误处理,提升用户体验
const [isLoading, setIsLoading] = useState(false); const matchData = async () => { setIsLoading(true); try { const formattedDate = dayjs().date(selectedDay).format('YYYY-MM-DD'); const url = `http://127.0.0.1:8000/${formattedDate}`; const res = await fetch(url); const d = await res.json(); setMatches(d.response); } catch (err) { console.error('数据获取失败:', err); // 可添加错误提示组件 } finally { setIsLoading(false); } }
内容的提问来源于stack exchange,提问作者Technic IT
相关产品推荐
相关产品推荐

