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

React打地鼠游戏中setInterval触发加速问题的原因及解决方案

问题原因及解决方案

问题原因

  1. 定时器重复创建:lightUp的依赖数组包含status,每次调用setStatus更新状态后,lightUp都会生成新的函数实例。而useEffect的依赖包含status和lightUp,这会导致每次状态更新或lightUp重建时,都会触发useEffect执行lightUp,进而创建新的定时器,旧定时器未被正确清理,最终多个定时器同时运行,导致触发速度加快。
  2. 清理函数错误:创建的是setInterval定时器,但清理时误用了clearTimeout,导致旧定时器无法被彻底清除。
  3. 时间间隔不符合需求:原代码设置的是1000毫秒(1秒),与期望的每2秒触发一次不符。

修复后的代码

function Grid({ number }) {
  const [status, setStatus] = useState(0);
  const array = Array(number).fill();

  const lightUp = useCallback(() => {
    // 调整为2000毫秒,满足每2秒触发的需求
    const timeId = setInterval(() => {
      // 生成与GridItem索引匹配的随机数(0到number-1)
      const item_id = Math.floor(Math.random() * number);
      console.log(item_id);
      setStatus(item_id);
    }, 2000);
    // 修复为clearInterval清理定时器
    return () => clearInterval(timeId);
  }, [number]); // 仅当number变化时重新创建lightUp

  useEffect(() => {
    const cleanup = lightUp();
    // 组件卸载或依赖更新时执行清理
    return cleanup;
  }, [lightUp]); // 仅当lightUp变化时触发Effect

  return (
    <div className='grid'>
      {array.map((e, idx) => {
        return <GridItem status={status} key={idx} index={idx} />;
      })}
    </div>
  );
}

export default Grid;

关键调整说明

  • 优化依赖逻辑:将lightUp的依赖数组改为[number],仅当网格数量变化时才重新创建函数,避免因status更新导致的重复生成。
  • 修复定时器清理:用clearInterval替代clearTimeout,确保旧定时器能被正确清除,避免多个定时器同时运行。
  • 匹配需求时间间隔:将setInterval的触发时间改为2000毫秒,符合每2秒点亮一个网格的需求。
  • 规范Effect清理:直接返回lightUp的清理函数,确保组件卸载或依赖更新时,旧定时器被及时清理,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:20:26