vardhaman
vardhaman

Reputation: 53

React for loop runs twice with array values not filled properly

React for loop run twice and Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. only array with even index are assigned values .

 import logo from './logo.svg';
    import './App.css';
    import Board from "./components/Board";
    import { useState, useEffect } from 'react';
    
    
    function App() {
      const [candyArray, setcandyArray] = useState([]);
        let n = 8, arr = [], i;
        for (i = 0; i < (n * n); i++) {
          arr[i] = Math.floor((Math.random() * n));
          i++;
        }
        setcandyArray(arr);
      console.log(candyArray);
      return (
        <Board />
      );
    }
    
    export default App;

Board js

export default function Board(props) {

    return (

        <div className="board">
            <div className="board-wrapper">
                <div className="candy-box" id="box1"></div>
                <div className="candy-box" id="box2"></div>
                <div className="candy-box" id="box3"></div>
                <div className="candy-box" id="box4"></div>
                <div className="candy-box" id="box5"></div>
                <div className="candy-box" id="box6"></div>
                <div className="candy-box" id="box7"></div>
                <div className="candy-box" id="box8"></div>
                <div className="candy-box" id="box9"></div>
                <div className="candy-box" id="box10"></div>
                <div className="candy-box" id="box11"></div>
                <div className="candy-box" id="box12"></div>
                <div className="candy-box" id="box13"></div>
                <div className="candy-box" id="box14"></div>
                <div className="candy-box" id="box15"></div>
                <div className="candy-box" id="box16"></div>
                <div className="candy-box" id="box17"></div>
                <div className="candy-box" id="box18"></div>
                <div className="candy-box" id="box19"></div>
                <div className="candy-box" id="box20"></div>
                <div className="candy-box" id="box21"></div>
                <div className="candy-box" id="box22"></div>
                <div className="candy-box" id="box23"></div>
                <div className="candy-box" id="box24"></div>
                <div className="candy-box" id="box25"></div>
                <div className="candy-box" id="box26"></div>
                <div className="candy-box" id="box27"></div>
                <div className="candy-box" id="box28"></div>
                <div className="candy-box" id="box29"></div>
                <div className="candy-box" id="box30"></div>
                <div className="candy-box" id="box31"></div>
                <div className="candy-box" id="box32"></div>
                <div className="candy-box" id="box33"></div>
                <div className="candy-box" id="box34"></div>
                <div className="candy-box" id="box35"></div>
                <div className="candy-box" id="box36"></div>
                <div className="candy-box" id="box37"></div>
                <div className="candy-box" id="box38"></div>
                <div className="candy-box" id="box39"></div>
                <div className="candy-box" id="box40"></div>
                <div className="candy-box" id="box41"></div>
                <div className="candy-box" id="box42"></div>
                <div className="candy-box" id="box43"></div>
                <div className="candy-box" id="box44"></div>
                <div className="candy-box" id="box45"></div>
                <div className="candy-box" id="box46"></div>
                <div className="candy-box" id="box47"></div>
                <div className="candy-box" id="box48"></div>
                <div className="candy-box" id="box49"></div>
                <div className="candy-box" id="box50"></div>
                <div className="candy-box" id="box51"></div>
                <div className="candy-box" id="box52"></div>
                <div className="candy-box" id="box53"></div>
                <div className="candy-box" id="box54"></div>
                <div className="candy-box" id="box55"></div>
                <div className="candy-box" id="box56"></div>
                <div className="candy-box" id="box57"></div>
                <div className="candy-box" id="box58"></div>
                <div className="candy-box" id="box59"></div>
                <div className="candy-box" id="box60"></div>
                <div className="candy-box" id="box61"></div>
                <div className="candy-box" id="box62"></div>
                <div className="candy-box" id="box63"></div>
                <div className="candy-box" id="box64"></div>
            </div>
        </div>
    )
}

i want to make an array with values randomly filled between 0 to 7 and this array stored in state value(candyArray) in react. thank you

Upvotes: 2

Views: 890

Answers (1)

Drew Reese
Drew Reese

Reputation: 202667

You have an unintentional side-effect in the component body. You likely are rendering you app into a React.Strictmode component that runs specific functions and methods twice as a way to help you detect unintnetional side-effect. One of these on-purpose double-invokations is the function body of function components. Since the side-effect is a state update this triggers a rerender. This is the render looping that React is complaining about.

Use a useEffect to run the effect once when the component mounts. Use a second useEffect hook to log when the candyArray state updates.

You also appear to be double incrementing your loop counter i, leading to only every other array element being updated. Remove the additional i++ from the loop body.

const Board = () => <div>Board</div>;

function App() {
  const [candyArray, setcandyArray] = React.useState([]);
  
  React.useEffect(() => {
    let n = 8, arr = [], i;
    for (i = 0; i < (n * n); i++) {
      arr[i] = Math.floor((Math.random() * n));
    }
    setcandyArray(arr);
  }, []);

  React.useEffect(() => {
    console.log(candyArray.map((el, i) => `[${i}->${el}]`));
  }, [candyArray]);

  return (
    <Board />
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App />,
  rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root" />

Upvotes: 1

Related Questions