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

React组件中使用for循环触发Too many re-renders错误原因咨询

React 无限重渲染错误原因分析

我在React自定义hook中编写了一个简单的for循环,想要通过push方法填充数组,却突然出现了“Too many re-renders. React limits the number of renders to prevent an infinite loop.”错误,想咨询该错误产生的原因。

相关代码:

import React, { useContext, useState } from "react";
import { MainContext } from "../contexts/context";
export default function useCreateBoard() {
  const contexts = useContext(MainContext);
  const [finalArray, setFinalArray] = useState([]);
  const [numberArrays, setNumbersArray] = useState([1, 2, 3, 4, 5, 6, 7, 8]);
  const [alphabetArray, setAlphabetArray] = useState([
    "a",
    "b",
    "c",
    "d",
    "e",
    "f",
    "g",
    "h",
  ]);
  const combinedArray = contexts.combineArrays(alphabetArray, numberArrays); // combine alphabets vs numbers return array of strings lik ==> 'a1'
  const [bgColor, setBgColor] = useState(true);

  for (let i = 0; i < combinedArray.length; i++) {
    //creating each game houses object here
    // pass them to final array
    // props => id , name , bgCol classes
    const chessHouses = {};
    chessHouses.id = i + 1;
    chessHouses.name = combinedArray[i];

    if (bgColor) {
      chessHouses.bgColorClass = "bg-black";
      setBgColor(false);
    } else {
      chessHouses.bgColorClass = "bg-white";
      setBgColor(true);
    }
    finalArray.push(chessHouses);
  }
  return [finalArray];
}

错误原因

  • 循环调用setState触发无限重渲染:
    你在hook的顶层代码里直接执行了setBgColor,React中只要调用setState,就会触发所在组件的重渲染。每次重渲染时,这个hook会重新执行,顶层的for循环又会再次调用setBgColor,再次触发重渲染,形成无限循环。

  • 直接修改state变量违反不可变原则:
    你直接用finalArray.push(chessHouses)修改useState返回的state数组,这会导致React无法正确追踪state变化,同时结合上述的setState调用,进一步加剧了循环问题。

修复思路

  1. 不要在hook/组件顶层直接执行会触发setState的代码,状态更新逻辑应该放在事件处理函数、useEffect或者useMemo这类受控环境中。
  2. 严格遵循React的state不可变原则,不要直接修改state变量,必须通过setter函数更新。
  3. 对于这种一次性生成的静态数组,用useMemo缓存计算结果,避免每次重渲染都重复生成:

修复后的示例代码:

import React, { useContext, useMemo } from "react";
import { MainContext } from "../contexts/context";

export default function useCreateBoard() {
  const contexts = useContext(MainContext);
  // 固定数组无需用state存储,直接用普通变量即可
  const numberArrays = [1, 2, 3, 4, 5, 6, 7, 8];
  const alphabetArray = ["a", "b", "c", "d", "e", "f", "g", "h"];
  const combinedArray = contexts.combineArrays(alphabetArray, numberArrays);

  // 用useMemo缓存计算结果,仅当combinedArray变化时重新计算
  const finalArray = useMemo(() => {
    let bgColor = true; // 用普通变量跟踪颜色,无需用state
    return combinedArray.map((item, index) => {
      const bgClass = bgColor ? "bg-black" : "bg-white";
      bgColor = !bgColor; // 切换普通变量,不调用setState
      return {
        id: index + 1,
        name: item,
        bgColorClass: bgClass
      };
    });
  }, [combinedArray]);

  return [finalArray];
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:27:38