Reputation: 482
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
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