Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

83
Views
UseEffect multiple re-renders

I'm trying to do a battleship game and this is my logic to generate the computer ships:

const ComputerBoard = ({ COLUMNS, ROWS }) => {
  const [layout, setLayout] = useState(new Array(ROWS * COLUMNS).fill('empty'));
  const newLayout = [...layout];

  useEffect(() => {
    const checkIfShipFits = (isHorizontal, spaces, i) => {
      let temp = 0;
      const x = i % ROWS;
      const y = Math.floor(i / COLUMNS);

      for (let n = 0; n < spaces; n += 1) {
        if (isHorizontal) {
          if (x + spaces < COLUMNS && newLayout[i + n] !== 'ship') {
            temp += 1;
          }
        }
        if (!isHorizontal) {
          if (y + spaces < ROWS && newLayout[i + COLUMNS * n] !== 'ship') {
            temp += 1;
          }
        }
      }

      return temp === spaces;
    };

    const generateComputerLayout = () => {
      const totalShips = computerShipsAvaibles;
      const boardSize = ROWS * COLUMNS;

      // Iterate over all types of ships
      for (let j = 0; j < totalShips.length; j += 1) {
        // Iterate over the amount of the specific ship
        for (let k = 0; k < totalShips[j].amount; k += 1) {
          let i = generateRandomIndex(boardSize);
          const isHorizontal = generateRandomDirection();

          while (!checkIfShipFits(isHorizontal, totalShips[j].spaces, i)) {
            i = generateRandomIndex(boardSize);
          }

          for (let l = 0; l < totalShips[j].spaces; l += 1) {
            if (isHorizontal) newLayout[i + l] = 'ship';
            if (!isHorizontal) newLayout[i + COLUMNS * l] = 'ship';
          }
        }
      }

      setLayout(newLayout);
    };

    generateComputerLayout();
  }, [COLUMNS, ROWS]);

  Math.floor(Math.random() * (COLUMNS * ROWS));

  return (
    <div>
      <h3>Computer</h3>
      <div className='board'>
        {layout.map((square, index) => (
          <div
            // eslint-disable-next-line react/no-array-index-key
            key={index}
            className={`square ${square} computer`}
          />
        ))}
      </div>
    </div>
  );
};

Currently it's working, but in the developer console throws the warning:

React Hook useEffect has a missing dependency: 'newLayout'. Either include it or remove the dependency array react-hooks/exhaustive-deps

When i add newLayout variable into the dependency array the app crashes due to useEffect multiple re-renders. How can I fix this error? Maybe I'm using the wrong way the useEffect.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

You effect is depending on the previous value of the state variable, so instead of having it as a dependency you can do the following:

const ComputerBoard = ({ COLUMNS, ROWS }) => {
  const [layout, setLayout] = useState(new Array(ROWS * COLUMNS).fill('empty'));

  useEffect(() => {
    setLayout((previousLayout) => {
      const newLayout = [...previousLayout];
      ...
      return newLayout;
    }
  }, [COLUMNS, ROWS]);
...

When you want the next state value to depend on the previous one, you should make use of "functional updates", which you can learn more about on the React documentation.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!