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

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();
}, [{}]);

问题分析与解决步骤

核心问题点

  1. URL使用双引号导致模板字符串${date}无法解析,请求地址错误
  2. useEffect依赖数组用[{}],既会重复触发请求,又没关联selectedDay状态,切换日期时不会触发新请求
  3. 获取到的data未同步到页面渲染用的matches状态

具体修复方案

  1. 修复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}`;
    
  2. 修正useEffect依赖:将依赖数组改为[selectedDay],确保日期切换时自动触发数据请求

    useEffect(() => {
        matchData();
    }, [selectedDay]);
    
  3. 同步数据到渲染状态:去掉冗余的data状态,直接将API返回的赛事数据赋值给matches

    const [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);
    }
    
  4. 可选优化:添加加载状态和错误处理,提升用户体验

    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:44:51