Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I start / stop setInterval?

I’ve tried different ways, but It doesn’t works.

[...]
  const [automatic, setAutomatic] = useState(false);

[...]
  var startAuto;

  useEffect(() => {
    if (!automatic) {
      console.log("stop");
      clearInterval(startAuto);
    } else {
      startAuto = setInterval(() => {
        changeQuestion("+");
      }, 5 * 1000);
    }
  }, [automatic]);

[...]
        <Button
          onPress={() => setAutomatic(!automatic)}
          title="turn on/off"
        />
[...]

It works when I put a setTimeout outside the useEffect, that way:

setTimeout(() => { clearInterval(startAuto); alert('stop'); }, 10000);

But I want to have a button to start / stop

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Your var startAuto; is redeclared on each render, and since changing the state causes a re-render, it never holds the reference to the interval, which is never cleared.

Use the useEffect cleanup function to clear the interval. Whenever automatic changes, it would call the cleanup (if returned by the previous invocation), and if automatic is true it would create a new interval loop, and return a new cleanup function of the current interval.

useEffect(() => {
  if(!automatic) return;
  
  const startAuto = setInterval(() => {
    changeQuestion("+");
  }, 5 * 1000);

  return () => {
    clearInterval(startAuto);
  };
}, [automatic]);

Working example:

const { useState, useEffect } = React;

const Demo = () => {
  const [automatic, setAutomatic] = useState(false);
  const [question, changeQuestion] = useState(0);
  
  useEffect(() => {
    if(!automatic) return;
    
    const startAuto = setInterval(() => {
      changeQuestion(q => q + 1);
    }, 5 * 100);

    return () => {
      clearInterval(startAuto);
    };
  }, [automatic]);

  return (
    <div>
      <button
        onClick={() => setAutomatic(!automatic)}
      >
        turn {automatic ? 'off' : 'on'}
      </button>
      
      <p>{question}</p>
    </div>
  );
}

ReactDOM
  .createRoot(root)
  .render(<Demo />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

<div id="root"></div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading