为何clearInterval/clearTimeout会使进度条自增变慢?需求:延迟5秒后每秒自增1
进度条延迟与自增速度异常的原因及修复方案
问题原因
- 重复触发的副作用:原代码中
useEffect的依赖包含progressBar,每次progressBar更新都会重新执行useEffect。每次执行时会先清除之前的定时器,再创建新的定时器,导致进度条的自增逻辑被反复中断、重启。如果调大延迟时长,这种中断重启的间隔会变长,直观上就会觉得自增速度变慢。 - 定时器参数错误:原代码中
setInterval的间隔设为10ms,本身就不符合“每秒自增1”的需求,再加上重复创建定时器的问题,进一步加剧了速度异常。
修复方案
修改useEffect的依赖为空数组,让副作用仅在组件挂载时执行一次,避免重复创建定时器。同时调整定时器参数,实现“先延迟5秒,之后每秒自增1”的需求。
修改后的完整代码
import React, { useState, useEffect } from 'react'; const ProgressBar = () => { const [progressBar, setProgressBar] = useState(0); let intervalId; useEffect(() => { // 初始延迟5秒 const timeoutId = setTimeout(() => { // 每秒执行一次进度更新 intervalId = setInterval(() => { setProgressBar(prevValue => { if (prevValue >= 100) { clearInterval(intervalId); return 100; } return prevValue + 1; }); }, 1000); }, 5000); // 组件卸载时清理所有定时器,防止内存泄漏 return () => { clearTimeout(timeoutId); clearInterval(intervalId); }; }, []); // 空依赖数组,仅组件挂载时执行一次 const divStyle = { backgroundColor: "green", width: `${progressBar}px`, maxWidth: "100px", border: "1px solid red", height: "20px", lineHeight: "20px", color: "#fff", textAlign: "center" }; return <div className='progress-bar' style={divStyle}>{progressBar}%</div>; }; export default ProgressBar;
代码关键说明
- 空依赖的useEffect:确保定时器只初始化一次,不会因
progressBar更新而重复创建,避免逻辑混乱。 - 定时器嵌套逻辑:先用
setTimeout实现5秒初始延迟,之后启动setInterval每秒更新一次进度。 - 进度终止判断:在
setProgressBar的更新函数中判断当前进度,达到100时立即清除定时器,停止自增。 - 清理函数:组件卸载时清除所有定时器,避免内存泄漏问题。
内容的提问来源于stack exchange,提问作者Almighty Dee
相关产品推荐
相关产品推荐

