ReactJS中如何检测Lichess API Rating History更新?
检测Lichess API数据变化并重新获取的方案(React + Node-Fetch)
1. 定时轮询(最简单直接的实现)
通过定时发起请求对比新旧数据,是最容易上手的方案。在React中用setInterval定期调用fetch,对比关键字段判断是否更新状态。
import { useEffect, useState } from 'react'; import fetch from 'node-fetch'; function LichessStats() { const [stats, setStats] = useState(null); const fetchStats = async () => { const res = await fetch('https://lichess.org/api/user/your-username'); const newStats = await res.json(); // 对比核心数据字段(比如等级分、对局数)判断是否更新 if (stats && JSON.stringify(stats.perfs) !== JSON.stringify(newStats.perfs)) { setStats(newStats); } else if (!stats) { setStats(newStats); } }; useEffect(() => { // 初始加载数据 fetchStats(); // 每5分钟轮询一次(间隔别太短,避免触发API限流) const interval = setInterval(fetchStats, 5 * 60 * 1000); return () => clearInterval(interval); }, [stats]); return ( <div>{stats ? <pre>{JSON.stringify(stats, null, 2)}</pre> : 'Loading...'}</div> ); }
2. 基于HTTP缓存头的条件请求(减少无效传输)
Lichess API会返回ETag或Last-Modified响应头,后续请求带上If-None-Match或If-Modified-Since头,服务器会返回304(未修改)或新数据,既能判断变化,又能节省带宽。
import { useEffect, useState } from 'react'; import fetch from 'node-fetch'; function LichessStats() { const [stats, setStats] = useState(null); const [etag, setEtag] = useState(''); const fetchStats = async () => { const options = etag ? { headers: { 'If-None-Match': etag } } : {}; const res = await fetch('https://lichess.org/api/user/your-username', options); if (res.status === 304) return; // 数据未变化,跳过更新 const newEtag = res.headers.get('ETag'); if (newEtag) setEtag(newEtag); const newStats = await res.json(); setStats(newStats); }; useEffect(() => { fetchStats(); const interval = setInterval(fetchStats, 5 * 60 * 1000); return () => clearInterval(interval); }, [etag]); return ( <div>{stats ? <pre>{JSON.stringify(stats, null, 2)}</pre> : 'Loading...'}</div> ); }
3. Lichess实时WebSocket API(真正的实时更新)
Lichess提供WebSocket接口,可监听用户数据变化(比如对局结束、等级分更新),服务器主动推送,无需轮询。
import { useEffect, useState } from 'react'; function LichessStats() { const [stats, setStats] = useState(null); useEffect(() => { // 初始加载基础数据 const fetchInitialStats = async () => { const res = await fetch('https://lichess.org/api/user/your-username'); const initialStats = await res.json(); setStats(initialStats); }; fetchInitialStats(); // 建立WebSocket连接监听用户事件 const ws = new WebSocket('wss://lichess.org/api/stream/user/your-username'); ws.onmessage = (event) => { const data = JSON.parse(event.data); // 根据事件类型更新对应数据(比如等级分变化) if (data.type === 'rating') { setStats(prev => ({ ...prev, perfs: { ...prev.perfs, [data.perf]: { ...prev.perfs[data.perf], rating: data.rating } } })); } // 可扩展处理对局结束等其他事件 }; // 处理连接异常与重连 ws.onerror = (error) => console.error('WebSocket error:', error); ws.onclose = () => { console.log('WebSocket closed, reconnecting...'); // 这里可添加自动重连逻辑 }; return () => ws.close(); }, []); return ( <div>{stats ? <pre>{JSON.stringify(stats, null, 2)}</pre> : 'Loading...'}</div> ); }
替代方案(若上述方法无法实现)
- 用户手动刷新:在页面添加刷新按钮,点击时触发fetch请求更新数据,适合对实时性要求低的场景。
- 后端缓存代理:如果项目有Node后端,在后端缓存Lichess数据并设置过期时间,前端请求后端接口,后端自动在缓存过期时拉取最新数据。
- Webhook推送:配置Lichess Webhook(需后端服务),当用户数据变化时,Lichess主动通知后端,后端再通过Socket.io等方式推送给前端更新。
内容的提问来源于stack exchange,提问作者HoodedHacker
相关产品推荐
相关产品推荐

