ReactJS中SetInterval在Chrome浏览器倒计时异常问题求助
React倒计时器在Chrome中变慢的修复方案
问题根源
原代码的核心问题在于useEffect依赖了timeLeft状态,每次timeLeft更新都会销毁旧定时器并创建新的。再加上JavaScript闭包特性,定时器回调里的timeLeft始终是创建该定时器时的旧值,叠加Chrome对后台标签页的定时器节流机制,最终导致倒计时逐渐变慢。
修复方案
- 移除
useEffect的timeLeft依赖,改用空数组,确保组件挂载时只创建一次定时器 - 使用
setTimeLeft的函数式更新形式,直接基于上一轮状态计算新值,彻底避开闭包陷阱
修复后的代码
import React, { useState, useEffect } from 'react'; import BaseModal from './Index'; export default function OtpModal(props: Props) { const [timeLeft, setTimeLeft] = useState<number>(120); useEffect(() => { const intervalId = setInterval(() => { // 函数式更新,直接获取上一轮状态值 setTimeLeft(prevTimeLeft => { if (prevTimeLeft <= 0) { clearInterval(intervalId); return 0; } return prevTimeLeft - 1; }); }, 1000); return () => clearInterval(intervalId); }, []); // 空依赖数组,仅组件挂载时执行一次 return ( <BaseModal> <div> OTP timeout in{' '} <span style={{ fontWeight: '500' }}> {Math.floor(timeLeft / 60)}: {(timeLeft % 60).toString().padStart(2, '0')} </span> </div> </BaseModal> ); }
额外优化说明
- 增加了倒计时结束时自动清除定时器的逻辑,避免不必要的资源消耗
- 该写法不会因状态更新频繁创建销毁定时器,在Chrome和Firefox中均能保持稳定的倒计时速度
内容的提问来源于stack exchange,提问作者labs
相关产品推荐
相关产品推荐

