Skip to content

Stop game loop on conditional with React

I am unable to stop the loop after a conditional. I am able to stop the interval after a button click but unable to stop it after a conditional such as loop increments. This simple example tries to stop the interval loop after 5 loops.

Any solutions would be much appreciated!

import React, { useState } from 'react';

let gameLoop: any;

function App() {
  const [loopCount, setLoopCount] = useState(0);
  const [running, setRunning] = useState(true);

  const gameLogic = () => {
    console.log('Game logic!')
  }

  const loop = () => {
    gameLogic();
    setLoopCount(prev => {
      const newCount = prev + 1;
      console.log(newCount)
      return newCount
    });

    // Stop the loop on a conditional
    if(loopCount >= 5){
      clearInterval(gameLoop)
    }
  }

  const handleStartButtonClick = () => {
    gameLoop = setInterval(loop, 1000)
    setRunning(true);
  }

  const handleStopButtonClick = () => {
    clearInterval(gameLoop);
    setRunning(false);
  }

  const handleResetButtonClick = () => {
    setLoopCount(0);
    console.clear();
  }

  return (
    <div className="App">
      <div>
        <button onClick={handleStartButtonClick}>Start</button>
        <button onClick={handleStopButtonClick}>Stop</button>
        <button onClick={handleResetButtonClick}>Reset</button>
      </div>
    </div>
  );
}

export default App;

Answer

The solution is to put the conditional at the component level, not in the loop method.

import React, { useState } from 'react';

let gameLoop: any;

function App() {
  const [loopCount, setLoopCount] = useState(0);
  const [running, setRunning] = useState(true);

  const gameLogic = () => {
    console.log('Game logic!')
  }

  const loop = () => {
    gameLogic();
    setLoopCount(prev => {
      const newCount = prev + 1;
      console.log(newCount)
      return newCount
    });


  }
    //MOVE OUTSIDE GAME LOOP
    // Stop the loop on a conditional
    if(loopCount >= 5){
      clearInterval(gameLoop)
    }

  const handleStartButtonClick = () => {
    gameLoop = setInterval(loop, 1000)
    setRunning(true);
  }

  const handleStopButtonClick = () => {
    clearInterval(gameLoop);
    setRunning(false);
  }

  const handleResetButtonClick = () => {
    setLoopCount(0);
    console.clear();
  }

  return (
    <div className="App">
      <div>
        <button onClick={handleStartButtonClick}>Start</button>
        <button onClick={handleStopButtonClick}>Stop</button>
        <button onClick={handleResetButtonClick}>Reset</button>
      </div>
    </div>
  );
}

export default App;