Nona
Nona

Reputation: 5462

How to get this button to reset the timer in this react component?

I have the following basic ReactJS setup with ES6. When I hit the reset button, the Timer does not go back to "0". What am I doing wrong? I'm pretty new to React so any code organization and other tips appreciated as well.

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      seconds: 0
    }
    this.resetTimer.bind(this)
  }
  resetTimer = () => {
    this.setState({seconds: 0})
  }
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
        <Button label="Start"/>
        <Button label="Stop"/>
        <Button label="Reset" onClick={this.resetTimer} />
        <Timer seconds={this.state.seconds} />
      </div>
    );
  }
}

class Button extends Component {
  render() {
    return(
      <div>
        <button onClick={this.props.onClick} >{this.props.label}</button>
      </div>
    );
  }
}

class Timer extends Component {
  constructor(props) {
    super(props)
    this.state = {
      seconds: this.props.seconds
    };
  }
  componentDidMount() {
    this.timerId = setInterval(
      () => this.tick(),
      1000
    );
  }
  tick() {
    this.setState({ seconds: this.state.seconds + 1});
  }
  componentWillUnmount() {
    clearInterval(this.timerId);
  }
  render() {
    return (
      <div>{secToMin(this.state.seconds)}</div>
    );
  }
}

export default App;

Upvotes: 1

Views: 2207

Answers (2)

Tharaka Wijebandara
Tharaka Wijebandara

Reputation: 8065

The problem is in your code is that you only assign seconds prop value to the state in your constructor. The constructor gets called only one time and after that, your changes to seconds prop doesn't update the state of the Timer component.

So you need to manually update the state when props get changed. You can use componentWillReceiveProps() life cycle method to do that as follows.

componentWillReceiveProps(nextProps){
  this.state = {
    seconds: nextProps.seconds
  };
}

Also, you don't actually need to bind this to resetTimer, as resetTimer is an arrow function. So you can safely remove the this.resetTimer.bind(this) line from your constructor.

Upvotes: 1

JacobW
JacobW

Reputation: 876

There are two ways for you to properly bind this to resetTimer;

The first option is for you to do this in your constructor

constructor(props) {
  super(props)
  this.state = {
    seconds: 0
  }
  this.resetTimer = this.resetTimer.bind(this)
}

and set your button like this <Button label="Reset" onClick={this.resetTimer} />

The second method is to not include this.resetTimer in your constructor at all, and on your button do this <Button label="Reset" onClick={this.resetTimer.bind(this)} />

There are two ways for you to properly bind this to resetTimer;

The first option is for you to do this in your constructor

constructor(props) {
  super(props)
  this.state = {
    seconds: 0
  }
  this.resetTimer = this.resetTimer.bind(this)
}

and set your button like this <Button label="Reset" onClick={this.resetTimer} />

The second method is to not include this.resetTimer in your constructor at all, and on your button do this <Button label="Reset" onClick={this.resetTimer.bind(this)} />

You've got a second issue though. Your button component probably doesn't work because your props aren't being set.

In your Button constructor do this:

 constructor(props) {
   super(props);
 }

Or change your button to a stateless component and write it like this:

function Button({onClick, label}) {
    return (
      <div>
        <button onClick={onClick} >{label}</button>
      </div>
    );
}

A third possible issue could be with your resetTimer function.

  resetTimer() {
    this.setState({seconds: 0})
  }

try writing it like the above and see if that works.

Upvotes: 0

Related Questions