Reputation: 45
I'm trying to build a countdown timer, which has a single button to toggle the start and the stop of the timer. Starting the timer and the switch between "break mode" and "session mode" works fine. The initial state of the countdown timer is paused. When I click on the Toggle Button it starts normally. When I click again, it doesn't do anything, it doesn't clear the interval. When I click again however, it doubles the interval.
Here is my code so far - the countdown function and the toggle function:
startstop() {
if (this.state.paused){
this.setState({
paused: false,
});
this.countdown(this.state.timerseconds, this.state.timerminutes, this.state.sessiontrue, this.state.paused);
} else if (!this.state.paused){
this.setState({
paused: true,
});
this.countdown(this.state.timerseconds, this.state.timerminutes, this.state.sessiontrue, this.state.paused);
}
}
countdown(seconds, minutes, sessionactive, pausedtrue){
let s = seconds;
let m = minutes;
let interval = setInterval(() => {
if (pausedtrue){
clearInterval(interval);
} else {
if (s === 0 && m > 0){
this.setState({
timerseconds: 59,
timerminutes: this.state.timerminutes - 1
})
s = 59;
m = m - 1;
} else if (s > 0 && m >= 0) {
this.setState({
timerseconds: this.state.timerseconds - 1,
timerminutes: this.state.timerminutes
})
s = s - 1;
} else if (s === 0 && m === 0){
if (sessionactive){
clearInterval(interval);
document.getElementById("beep").play();
this.setState({
timerseconds: 0,
timerminutes: this.state.breaklength,
sessiontrue: false,
});
this.countdown(this.state.timerseconds, this.state.timerminutes, this.state.sessiontrue, false);
} else {
clearInterval(interval);
document.getElementById("beep").play();
this.setState({
timerseconds: 0,
timerminutes: this.state.sessionlength,
sessiontrue: true,
});
this.countdown(this.state.timerseconds, this.state.timerminutes, this.state.sessiontrue, false)
}
}
}
}
, 1000)
}
Upvotes: 0
Views: 122
Reputation: 3573
Every time you call countdown
you create a new interval. You should store the reference to the first interval somewhere and use that reference in clearInterval
when you click to pause the timer.
Another approach would be to use this.state.paused
instead of pausedtrue
in if (pausedtrue)
, because pausedtrue
is set when you call the method and never changes but this.state.paused
can be changed and will be checked every tick.
Also I think it's not safe to use this.state.paused
when you call the countdown
. setState
is asynchronous so you never know if the value in the state has been already changed or not.
Upvotes: 1