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

React:使用useEffect根据状态值修改div颜色时计数器到99后div消失

React加载计数器异常问题解决

问题场景

我有一个内部包含计数器的div,渲染代码如下:

return (
  <div 
    className="loading-div"
    style={styles}
  >
    <h1>Loading {count} %</h1>
  </div>
);

计数器通过useEffect钩子中的setTimeout每0.1秒更新一次,代码如下:

useEffect((e) => {
  setTimeout(() => {
    count === 100 ? e.preventDefault() : setCount(() => count + 1);
    count === 35 ? setFont(() => font + 6) : setCount(() => count + 1);
    count === 70 ? setWidth(() => width + 100) : setCount(() => count + 1);
    count === 70 ? setHeight(() => height + 100) : setCount(() => count + 1);
    count === 99 ? setColor(() => color="lime") : setCount(() => count + 1);
  }, 100);
})

运行到计数器到达99时,div消失了。猜测fontSize、width/height的修改生效是因为用了font + 5的方式,但setColor函数不生效是因为赋值后状态未立即改变?如何让计数器到达99时状态立即改变?


问题分析

  1. useEffect无依赖项+多次setCount:每次组件渲染都会创建新的setTimeout,且每个条件分支都会调用setCount,导致count被快速累加,逻辑混乱。
  2. setColor写法错误:setColor(() => color="lime")是错误的状态更新写法,函数式更新需要返回新值而非执行赋值语句,直接使用setColor("lime")即可。
  3. e.preventDefault()报错:useEffect的回调参数不是事件对象,e为undefined,调用该方法会抛出错误,这就是div消失的直接原因。
  4. 状态更新异步特性:React状态更新是异步的,不能依赖当前count值同步判断后续操作,需用函数式更新获取最新状态。

修正后的代码方案

import { useState, useEffect } from 'react';

function LoadingComponent() {
  const [count, setCount] = useState(0);
  const [font, setFont] = useState(16);
  const [width, setWidth] = useState(200);
  const [height, setHeight] = useState(100);
  const [color, setColor] = useState("gray");

  useEffect(() => {
    if (count >= 100) return;
    
    const timer = setTimeout(() => {
      setCount(prevCount => {
        const newCount = prevCount + 1;
        
        if (newCount === 36) {
          setFont(prevFont => prevFont + 6);
        }
        if (newCount === 71) {
          setWidth(prevWidth => prevWidth + 100);
          setHeight(prevHeight => prevHeight + 100);
        }
        if (newCount === 100) {
          setColor("lime");
        }
        
        return newCount;
      });
    }, 100);

    return () => clearTimeout(timer);
  }, [count]);

  const styles = {
    width: `${width}px`,
    height: `${height}px`,
    fontSize: `${font}px`,
    color: color,
    border: "1px solid #ccc",
    display: "flex",
    alignItems: "center",
    justifyContent: "center"
  };

  return (
    <div 
      className="loading-div"
      style={styles}
    >
      <h1>Loading {count} %</h1>
    </div>
  );
}

export default LoadingComponent;

关键修正点

  • 添加useEffect依赖项:将count作为依赖,确保每次count更新后才创建新定时器,避免无限循环。
  • 合并count更新逻辑:在setCount的函数式更新中统一处理所有状态变化,确保基于最新count值判断。
  • 修正setColor写法:直接传递新值"lime",保证状态更新生效。
  • 清除定时器:在useEffect清理函数中清除定时器,防止内存泄漏。
  • 移除错误的preventDefault调用:通过count >=100判断停止定时器,避免报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:36:51