Reputation: 5761
I have implemented a vanilla js countdown into a react component as follow:
import React, { Component } from 'react';
class CustomCountDown extends Component {
constructor(props) {
super(props);
this.endTime;
this.msLeft;
this.time;
this.hours;
this.mins;
this.element;
}
twoDigits( n ){
return (n <= 9 ? "0" + n : n);
}
updateTimer() {
this.msLeft = this.endTime - (+new Date);
if (this.msLeft < 1000 ) {
element.innerHTML = "countdown's over!";
} else {
this.time = new Date(this.msLeft );
this.hours = this.time.getUTCHours();
this.mins = this.time.getUTCMinutes();
this.element.innerHTML = (this.hours ? this.hours + ':' + this.twoDigits( this.mins ) : this.mins) + ':' + this.twoDigits( this.time.getUTCSeconds() );
setTimeout( this.updateTimer, this.time.getUTCMilliseconds() + 500 );
}
}
countdown( elementName, minutes, seconds ) {
this.element = document.getElementById( elementName );
this.endTime = (+new Date) + 1000 * (60*minutes + seconds) + 500;
this.updateTimer();
}
componentDidMount() {
this.countdown("count", 1, 30);
}
render() {
return(
<div id="count">
</div>
);
}
}
export default CustomCountDown;
I can't figure out why I am getting the following error:
Upvotes: 1
Views: 82
Reputation: 44967
When you pass this.updateTimer
to setTimeout
you loose context, i.e. this
no longer points to your component instance. You need to keep the context either way:
setTimeout( this.updateTimer.bind(this), this.time.getUTCMilliseconds() + 500 );
setTimeout( () => this.updateTimer(), this.time.getUTCMilliseconds() + 500 );
As a better alternative, you can bind updateTimer
in the constructor. This won't create new function every time updateTimer
is called:
constructor(props) {
// ...
this.updateTimer = this.updateTimer.bind(this);
}
Upvotes: 3