Search code examples
reactjsfor-loopinfinite-loop

Too many re-renders. React limits the number of renders to prevent an infinite loop. with for loop


I wrote a simple for inside my react component. then I wanted fill an array with push method inside it. then suddenly I findout this error "Too many re-renders. React limits the number of renders to prevent an infinite loop." but why ??

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];
}```

Solution

  • setBgColor(false);
    

    You're setting state in the middle of rendering. Setting state causes the component to rerender, and then you set state again, which renders again, which sets state again, which renders again, etc.

    I don't see why this is a state. I think you just meant to have a local variable:

    let bgColor = true;
    
    for (let i = 0; i < combinedArray.length; i++) {
      //...
      if (bgColor) {
        chessHouses.bgColorClass = "bg-black";
        bgColor = false;
      } else {
        chessHouses.bgColorClass = "bg-white";
        bgColor = true;
      }
      finalArray.push(chessHouses);
    }
    return [finalArray];
    
    

    Or you could alternate colors by checking if i is divisible by 2:

    for (let i = 0; i < combinedArray.length; i++) {
      //...
      if (i % 2 === 0) {
        chessHouses.bgColorClass = "bg-black";
      } else {
        chessHouses.bgColorClass = "bg-white";
      }
      finalArray.push(chessHouses);
    }