Bojan Mitic
Bojan Mitic

Reputation: 482

Setting up a variable in setInterval(), react

I'm trying to setup a pause variable inside setInterval() function, after few times pressing button pause it became to act weirdly, it's not same like outer variable. What i'm doing wrong? Run code snippet, and press pause few times

const {useState, useEffect} = React
        
        function App() {
          const [pause, setPause] = useState(false)
          const [innerVar, setInnerVar] = useState(false)
          const [outerVar, setOuterVar] = useState(false)
          useEffect(()=>{
            setOuterVar(pause)
          }, [pause])
        
          const interval = setInterval(function() {
            setInnerVar(pause) 
          }, 2000)
        
          return (
            <div>
              <button onClick={() => setPause(!pause)}>Pause</button>
              <div>Pause variable: {pause ? 'true': 'false'}</div>
              <div>Inside setInteval: {innerVar ? 'true' : 'false'}</div>
              <div>Outside setInterval: {outerVar ? 'true' : 'false'}</div>
          </div>
          )
        }
        
    ReactDOM.render(<App />, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

Upvotes: 2

Views: 2210

Answers (1)

vatz88
vatz88

Reputation: 2452

1) You're not clearing the interval.

2) According to your code, a new interval is set each time the component is rendered.

Set the interval in useEffect so that it is consistent with when the pause value changes and then clear the interval in the clean-up function.

const {useState, useEffect} = React
        
        function App() {
          const [pause, setPause] = useState(false)
          const [innerVar, setInnerVar] = useState(false)
          const [outerVar, setOuterVar] = useState(false)
          useEffect(()=>{
            setOuterVar(pause);
            const interval = setInterval(function() {
              setInnerVar(pause) 
            }, 2000);
            return ()=>{clearInterval(interval);};
          }, [pause]);
        
          return (
            <div>
              <button onClick={() => setPause(!pause)}>Pause</button>
              <div>Pause variable: {pause ? 'true': 'false'}</div>
              <div>Inside setInteval: {innerVar ? 'true' : 'false'}</div>
              <div>Outside setInterval: {outerVar ? 'true' : 'false'}</div>
          </div>
          )
        }
        
    ReactDOM.render(<App />, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

UPDATE

From @Alexfrostwolf answer, you don't really need setInterval in this case now and use setTimeout instead. Though, will leave my answer with minimum modification from you code.

Upvotes: 1

Related Questions