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

React中使用useEffect+setInterval循环数组切换状态异常问题

问题:React使用useEffect+setInterval循环展示月份数组异常

我想要遍历包含["1", "2", "3"]的月份数组,每2秒展示当前月份。尝试使用useEffect、useState和setInterval实现循环,但出现不符合预期的行为。

代码如下:

import { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const months = ["1", "2", "3"];
  let count = 0;
  const [month, setMonth] = useState(months[count]);
  useEffect(() => {
    function cycleArray() {
      setMonth(months[count]);
      // increment our counter
      count++;
      // reset counter if we reach end of array
    }
    if (count === months.length) {
      count = 0;
    }
    setInterval(cycleArray, 1000);
  }, [count]);
  return (
    <div className="App">
      <h1>Loop over months (next month every 1 second) </h1>
      <h2>{month}</h2>
    </div>
  );
}

请问我哪里出错了?


错误分析与解决方案

核心错误点

  1. count使用普通变量而非状态变量
    组件每次渲染时,let count = 0都会重新初始化,加上useEffect依赖数组包含count,会导致每次count变化都创建新的定时器,多个定时器同时运行,逻辑彻底混乱。

  2. 计数器重置逻辑位置错误
    你把count重置的判断写在了useEffect外层,仅在useEffect执行时才会检查,不会在每次循环回调中触发,导致count会超出数组长度,最终取到undefined。

  3. 未清理定时器
    没有清除旧的定时器,每次count变化都会新增定时器,导致更新频率远高于预期,同时造成内存泄漏。

修正后的代码

import { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const months = ["1", "2", "3"];
  // 将count改为状态变量,让React追踪其变化
  const [count, setCount] = useState(0);
  const [month, setMonth] = useState(months[count]);

  useEffect(() => {
    const intervalId = setInterval(() => {
      // 更新当前展示的月份
      setMonth(months[count]);
      // 函数式更新count,确保拿到最新值并处理循环
      setCount(prevCount => {
        const next = prevCount + 1;
        return next === months.length ? 0 : next;
      });
    }, 2000); // 改为2秒,匹配需求

    // 清理函数:组件卸载或依赖变化时清除定时器
    return () => clearInterval(intervalId);
  }, [count, months]);

  return (
    <div className="App">
      <h1>Loop over months (next month every 2 seconds) </h1>
      <h2>{month}</h2>
    </div>
  );
}

修正说明

  • 把count换成状态变量,让React能正确追踪其变化,避免每次渲染重置初始值。
  • 在定时器回调中用函数式更新setCount,确保每次都基于最新的count值计算下一个索引,同时内置循环重置逻辑。
  • 添加定时器清理函数,防止组件卸载后定时器继续运行,也避免多个定时器同时触发。
  • 将定时器间隔调整为2000ms,符合你最初的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:16:07