如何在React中实现支持时分秒渲染的可重启倒计时功能
React倒计时功能实现方案
第一步:定义核心状态
在函数组件中声明三个核心状态:
remainingSeconds:存储剩余总秒数,用于计算时分秒timerId:存储定时器实例ID,用于及时清除定时器避免内存泄漏- 初始总时长常量:用于倒计时重置时复用,可根据需求自行修改数值,也可改为组件props传入实现自定义时长
import { useState, useEffect, useCallback } from 'react'; // 示例初始值为1小时,单位为秒 const INITIAL_TOTAL_SECONDS = 60 * 60; const CountdownTimer = () => { const [remainingSeconds, setRemainingSeconds] = useState(INITIAL_TOTAL_SECONDS); const [timerId, setTimerId] = useState(null);
第二步:封装时分秒格式化方法
将总秒数转换为带前导零的时分秒格式,方便页面渲染:
const formatTime = useCallback((totalSec) => { const hours = Math.floor(totalSec / 3600); const minutes = Math.floor((totalSec % 3600) / 60); const seconds = totalSec % 60; return { hours: String(hours).padStart(2, '0'), minutes: String(minutes).padStart(2, '0'), seconds: String(seconds).padStart(2, '0') } }, []);
第三步:实现倒计时自动递减逻辑
通过useEffect监听剩余时间变化,自动启停定时器,组件卸载时自动清除定时器:
useEffect(() => { // 剩余时间归0时停止倒计时 if (remainingSeconds <= 0) { timerId && clearInterval(timerId); return; } // 启动每秒递减的定时器 const id = setInterval(() => { setRemainingSeconds(prev => prev - 1); }, 1000); setTimerId(id); // 依赖更新/组件卸载时清除旧定时器 return () => clearInterval(id); }, [remainingSeconds, timerId]);
第四步:实现重启倒计时功能
const handleRestart = () => { // 先清除正在运行的旧定时器 timerId && clearInterval(timerId); // 重置剩余时间为初始值,会自动触发useEffect重启倒计时 setRemainingSeconds(INITIAL_TOTAL_SECONDS); }
第五步:页面渲染逻辑
const { hours, minutes, seconds } = formatTime(remainingSeconds); return ( <div className="timer-wrapper"> <div className="time-display"> <span>{hours}</span>: <span>{minutes}</span>: <span>{seconds}</span> </div> <button onClick={handleRestart}>重新启动倒计时</button> </div> ) } export default CountdownTimer;
优化提示
- 对计时精度要求高的场景,可使用
requestAnimationFrame替代setInterval,避免主线程阻塞导致的计时偏差 - 页面切后台后定时器会被浏览器降速,如需后台正常计时,可监听
visibilitychange事件,在页面切回时用时间戳修正剩余时间
内容的提问来源于stack exchange,提问作者Tolga Günaydın
相关产品推荐
相关产品推荐

