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

React中如何实现每秒自动生成随机数并更新进度条渲染

问题根因

你的代码不生效有4个核心问题:

  • 同时混用setTimeout和setInterval,会导致定时器重复叠加触发,执行逻辑混乱
  • number是定义在组件外的普通全局变量,值修改后不会触发React组件重渲染,界面自然不会更新
  • 所有styled-components组件都写在render方法内部,每次组件重渲染都会重新生成新的组件实例,既影响性能也会导致动画异常
  • 没有做定时器清理逻辑,组件卸载后定时器还在后台运行会造成内存泄漏
正确实现方案

把styled组件移到组件外部避免重复创建,用组件state存储随机数值,在组件挂载时启动定时器、卸载时清除定时器,只保留一个setInterval做每秒更新即可:

import React from 'react'
import styled, { keyframes } from 'styled-components'

// 所有styled组件移到组件外,全局只初始化一次
const ProgressContainer = styled.div`
    margin-bottom: 25px;
`
const Text = styled.span`
    font-size: 17px;
    font-family: Poppins;
    color: #fff;
`
const Value = styled.span`
    font-size: 17px;
    font-family: Poppins;
    color: #fff;
    float: right;
`
const ColorAnimation = keyframes`
    0%  {background: #04e5e5;}
    10% {background: #f37055;}
    20% {background: #ef4e7b;}
    30% {background: #a166ab;}
    40% {background: #5073b8;}
    50% {background: #04e5e5;}
    60% {background: #07b39b;}
    70% {background: #6fba82;}
    80% {background: #5073b8;}
    90% {background: #1098ad;}
    100% {background: #f37055;}
`
const Progress = styled.div`
    height: 5px;
    border-radius: 2.5px;
    margin-top: 10px;
    transition: width 1s ease;
    animation: ${ColorAnimation} 10s infinite alternate;
`

class ProgressBar extends React.Component {
    // 初始化state存储进度值
    state = {
        number: 0
    }

    timer = null

    // 组件挂载后启动定时器
    componentDidMount() {
        this.timer = setInterval(() => {
            // 生成1-100的随机数,更新state触发重渲染
            this.setState({
                number: Math.floor((Math.random()*100)+1)
            })
        }, 1000)
    }

    // 组件卸载前清除定时器,避免内存泄漏
    componentWillUnmount() {
        if (this.timer) {
            clearInterval(this.timer)
        }
    }

    render() {
        const { text } = this.props
        const { number } = this.state
        return(
            <ProgressContainer>
                <Text>{text}</Text>
                <Value>{number}%</Value>
                <Progress style={{width: `${number}%`}}></Progress>
            </ProgressContainer>
        )
    }
}

export default ProgressBar
关键改动说明
  • 移除全局的number变量,改用组件内部state存储进度值,调用setState更新时React会自动触发重渲染刷新界面
  • 删掉重复的定时器逻辑,只保留一个setInterval每秒生成一次随机数
  • 所有styled组件移到组件外部,避免每次渲染重复创建组件实例
  • 新增生命周期逻辑,组件卸载时清除定时器,防止内存泄漏
  • 给Progress的width属性单独加了过渡效果,进度条变化时更顺滑,避免和颜色动画冲突

注意不要在render方法里定义styled组件,styled-components会在每次组件实例化时给新组件生成唯一类名,会导致浏览器反复重绘DOM,性能损耗非常大。

内容的提问来源于stack exchange,提问作者user1149727

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.13 16:15:55