You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何clearInterval/clearTimeout会使进度条自增变慢?需求:延迟5秒后每秒自增1

进度条延迟与自增速度异常的原因及修复方案

问题原因

  1. 重复触发的副作用:原代码中useEffect的依赖包含progressBar,每次progressBar更新都会重新执行useEffect。每次执行时会先清除之前的定时器,再创建新的定时器,导致进度条的自增逻辑被反复中断、重启。如果调大延迟时长,这种中断重启的间隔会变长,直观上就会觉得自增速度变慢。
  2. 定时器参数错误:原代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:18:28