I have a timer using setInterval()
in a React component and I'm unsure what the best practices are in order to start and stop this interval in respect to using state
. I'm running into some asynchronous issues with that.
Let's say I have a set of links in my React component that render and execute the callback fine:
let links = [10, 50, 100, 500, 1000].map((num) => {
return(
<Link key={num} onClick={(e) => this.switchNums(num)} to={`/somePath/${num}`}>{num}</Link>
)
})
Here's the switchNums()
function, where i want it to reset an existing timer:
switchNums(num){
this.stopTimer()
this.reset(num)
}
Here's startTimer()
, stopTimer()
and reset()
:
startTimer(){
if(!this.state.timerId){
let timerId = setInterval(()=>{
let timer = this.state.timer + 1
this.setState({
timer: timer,
timerId: timerId
})
}, 1000)
}
}
stopTimer(){
clearInterval(this.state.timerId)
this.setState({timerId:null})
}
reset(size){
this.setState({
gameOver: false,
counter: 0,
correct: 0,
numbers: this.getRandomNumbers(size),
timer: 0
}, this.startTimer())
}
One of the bugs is clicking on the links rapidly will cause multiple intervals to fire despite the if
condition in startTimer()
. I'm guessing this has to do with the asynchronous nature of setState()
. Another bug (and I think related) is that when i click slowly, it only starts the interval every other time.
Can anyone shed some light on this? Or what they've done to circumvent asynchronous issues with setState
being used in conjunction with setInterval
(any way set state can return a promise?), Or which lifecycle methods would be best for this type of situation?