I have seen lots of countdown timers in JavaScript and wanted to get one working in React.
I have borrowed this function I found online:
secondsToTime(secs){
let hours = Math.floor(secs / (60 * 60));
let divisor_for_minutes = secs % (60 * 60);
let minutes = Math.floor(divisor_for_minutes / 60);
let divisor_for_seconds = divisor_for_minutes % 60;
let seconds = Math.ceil(divisor_for_seconds);
let obj = {
"h": hours,
"m": minutes,
"s": seconds
};
return obj;
};
And then I have written this code myself
initiateTimer = () => {
let timeLeftVar = this.secondsToTime(60);
this.setState({ timeLeft: timeLeftVar })
};
startTimer = () => {
let interval = setInterval(this.timer, 1000);
this.setState({ interval: interval });
};
timer = () => {
if (this.state.timeLeft >0){
this.setState({ timeLeft: this.state.timeLeft -1 });
}
else {
clearInterval(this.state.interval);
//this.postToSlack();
}
};
Currently onclick it will set the time on screen to: Time Remaining: 1 m : 0 s
But it does not reduce it to Time Remaining: 0 m : 59 s
and then Time Remaining: 0 m : 58 s
etc etc
I think I need to call the function again with a different parameter. how can I go about doing this ?
Edit: I forgot to say, I would like the functionality so that I can use seconds to minutes & seconds
The one downside with
setInterval
is that it can slow down the main thread. You can do a countdown timer usingrequestAnimationFrame
instead to prevent this. For example, this is my generic countdown timer component:The problem is in your "this" value. Timer function cannot access the "state" prop because run in a different context. I suggest you to do something like this:
As you can see I've added a "bind" method to your timer function. This allows the timer, when called, to access the same "this" of your react component (This is the primary problem/improvement when working with javascript in general).
Another option is to use another arrow function:
You have to
setState
every second with the seconds remaining (every time the interval is called). Here's an example: