简体   繁体   中英

Unhandled Runtime Error TypeError: Cannot read property 'timer' of undefined

I am creating a stopwatch using React. I hit the start button and the stopwatch starts, but when I hit the stop button I receive a TyperError

 import React from 'react'; class Home extends React.Component { constructor(props) { super(props); this.state = {secondsElapsed: 0}; this.handleStartClick = this.handleStartClick.bind(this); } getSeconds() { return ('0' + this.state.secondsElapsed % 60).slice(-2); } getMinutes() { return Math.floor(this.state.secondsElapsed / 60); } getHours() { return Math.floor((this.state.secondsElapsed / 60) / 60); } handleStartClick() { this.timer = setInterval(() => { this.setState({ secondsElapsed: (this.state.secondsElapsed + 1) }); }, 1000) } handleStopClick() { clearInterval(this.timer); } render() { return ( <div> <h1>{this.getHours()}:{this.getMinutes()}:{this.getSeconds()}</h1> <button type="button" onClick={this.handleStartClick}> start </button> <button type="button" onClick={this.handleStopClick}> stop </button> </div> ); } } export default Home;

The stopwatch will continue to run even after the error. I was wondering if it was unable to read this.timer because it was created in a function, handleStartClick .

You forgot to bind this to handleStopClick . By not doing so this isn't the this of the component.

constructor(props) {
    super(props);
    this.state = {secondsElapsed: 0};
    this.handleStartClick = this.handleStartClick.bind(this);
    this.handleStopClick = this.handleStopClick.bind(this);
}

It is easy to avoid this by using arrow functions, they bind this of the parent for you.

handleStartClick = () => {
    this.timer = setInterval(() => {
        this.setState({
            secondsElapsed: (this.state.secondsElapsed + 1)
        });
    }, 1000)
}

handleStopClick = () => {
    clearInterval(this.timer);
}

You have already correctly bound handleStartClick in the constructor:

this.handleStartClick = this.handleStartClick.bind(this);

You need to do the same with handleStopClick :

this.handleStopClick = this.handleStopClick.bind(this);

The reason is the same in both cases - to make sure that any reference to this inside either function still refers to the component instance. Otherwise, when called as an event handler, the "context is lost", and this becomes undefined - as you're seeing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM