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调用,进一步加剧了循环问题。
修复思路
- 不要在hook/组件顶层直接执行会触发setState的代码,状态更新逻辑应该放在事件处理函数、useEffect或者useMemo这类受控环境中。
- 严格遵循React的state不可变原则,不要直接修改state变量,必须通过setter函数更新。
- 对于这种一次性生成的静态数组,用
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
相关产品推荐
相关产品推荐

