React Countdown Circle Timer标签页非激活时动画不启动求助
解决react-countdown-circle-timer标签页未激活时不启动的问题
问题说明
- 使用react-countdown-circle-timer包开发游戏计时器
- 业务逻辑:第二名玩家加入时后端启动计时器,前端设置
isPlaying={true} - 异常表现:当前标签页激活时,圆形动画正常启动;标签页未激活时,即便
isPlaying设为true,动画也不会启动,只有切回该标签页才会开始 - 该问题与该包的GitHub issue #31完全一致
解决方案实现
核心思路是抛弃浏览器requestAnimationFrame的依赖,改用后端时间戳做基准同步计时,具体代码实现如下:
import { useState, useEffect } from 'react'; import { CountdownCircleTimer } from 'react-countdown-circle-timer'; const GameTimer = ({ totalGameTime, timerStartTimestamp, isGameStarted }) => { const [remainingTime, setRemainingTime] = useState(totalGameTime); useEffect(() => { let intervalId; if (isGameStarted && timerStartTimestamp) { // 实时计算剩余时间的方法 const updateRemainingTime = () => { // 基于后端起始时间戳计算已流逝时间 const elapsedMs = Date.now() - timerStartTimestamp; const newRemaining = Math.max(totalGameTime - Math.floor(elapsedMs / 1000), 0); setRemainingTime(newRemaining); // 时间到了就清除定时器 if (newRemaining === 0) { clearInterval(intervalId); } }; // 初始化计算一次 updateRemainingTime(); // 每秒更新一次剩余时间 intervalId = setInterval(updateRemainingTime, 1000); } // 组件卸载时清除定时器 return () => clearInterval(intervalId); }, [isGameStarted, timerStartTimestamp, totalGameTime]); return ( <CountdownCircleTimer isPlaying={true} // 保持播放状态,由外部控制剩余时间 duration={totalGameTime} initialRemainingTime={remainingTime} onComplete={() => ({ shouldRepeat: false })} > {({ remainingTime }) => <span>{remainingTime}</span>} </CountdownCircleTimer> ); }; export default GameTimer;
关键逻辑说明
- 依赖后端提供的计时器启动时间戳,避免浏览器标签页休眠导致的计时偏差
- 通过
setInterval每秒计算一次剩余时间,手动更新组件的initialRemainingTime - 组件的
isPlaying始终设为true,只负责根据传入的剩余时间渲染动画,计时逻辑完全由外部控制
效果验证
标签页未激活时,前端会持续基于后端时间戳计算剩余时间,切回标签页时动画会直接同步到正确的剩余状态,彻底解决标签页休眠导致的动画不启动问题
内容的提问来源于stack exchange,提问作者Mave
相关产品推荐
相关产品推荐

