javascriptnode.jsreactjssetintervalgame-loop

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;

Solution

  • 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;