Reputation: 3821
I'm trying to work out how to do a pre-game countdown in a Game component in React. I'm trying like this, but it's saying that this.countDown
isn't a function - when it's clearly defined.
Can someone point out where I'm going wrong?
class Game extends Component {
constructor() {
super();
this.state = {
timer: 5,
isHidden: true,
randomIndex: 0,
score: 0
};
this.countDown = this.countDown.bind(this);
}
countDown() {
this.setState({
timer: this.state.timer--
});
}
render() {
const tables = this.props.tables.map(table => {
return (
<li key={table.uniqueId}>
{table.timesTable[0]} X {table.timesTable[1]}
</li>
);
});
setInterval(function() {
this.countDown();
console.log(this.state.timer);
}, 1000);
// if (this.state.timer > 0) {
// this.countDown();
// }
return (
<div className="Game">
<h3>Current Tables are:</h3>
{tables}
<h1 id="countdown">{this.state.timer}</h1>
<Question />
{/* question handles the right or wrong logic, receives a random timestable */}
<h3>Score: {this.state.score}</h3>
<button onClick={this.stopGame}>Stop Game</button>
<button onClick={this.startOver}>Start Over</button>
</div>
);
}
}
export default Game;
Upvotes: 0
Views: 1721
Reputation: 20027
In that example, this
in setInterval
's callback refers to the global window
object, since it's executed as window.setInterval(...)
, so this.countDown()
would be equal to window.countDown()
, which is obviously incorrect.
To get this
from parent's scope, you could use arrow functions.
setInterval(() => {
this.countDown();
console.log(this.state.timer)
}, 1000);
or simply bind this:
setInterval(function() {
this.countDown();
console.log(this.state.timer)
}.bind(this), 1000); // bind this from parent's scope
Upvotes: 3