Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

84
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda