React - Component with 2 conditional options (different props), state doesn't update

So, I’m trying to build a button which when clicked toggles between the 25 minute timer, and 5 minute break timer. On click the button text changes fine, and if I check React Dev Tools, the correct prop of 1500 seconds/300 seconds is being passed into the Timer component, however the state does not update. When I click the reset button the state is then updated and the correct time value is displayed. Why is the correct props being passed to Timer but the Timer state is not being updated by the following code?

The conditionally rendered component is in the code below stored in the timer variable.

render() {
    const timer = this.state.break ? 
      <Timer seconds="300" /> : 
      <Timer seconds="1500" />;
    return (
      <div>
        <div>
          <button onClick={this.toggleBreak}>
            {this.state.break ? "Break" : "Pomodoro"}
          </button>
          {timer}
        </div>
      </div>
    );
  }
}

class Timer extends React.Component {
  constructor(props) {
    super();

    this.state = {
      seconds: props.seconds,
      active: false
    };
  }

It’s hard to say without seeing the toggleBreak function. Timer’s state has to be changed in order for it to re-render. I’m not familiar with this challenge, but you may need to attach a function to the button that updates Timer’s state. Do you know how to this.setState( () => { return {prop: newProp}; ?

I linked a codepen in the post showing the code. I don’t think I’ve used setState in that way before, no.

Sorry, I can’t figure it out! I notice it does render correctly with the Reset button, though. You could probably use that.

It looks to me that you are correctly passing the state down through the props, and when the props change, it should re-render (I thought). But I’m rather new to React , so there must be something I’m missing.

The reset button is using setState to re render the number, for some reason the isn’t causing a render. No idea how to fix it.

If you’re setting props to state you have to listen to props change. In class based components it’s usually done via componentDidUpdate.
Add this to your Timer component:

  componentDidUpdate(prevProps) {
    if (this.props.seconds !== prevProps.seconds) {
      this.setState({ seconds: this.props.seconds });
    }
  }

Thank you, it works! I was trying to use shouldComponentUpdate and couldn’t quite get there.

Would you refactor the code in any way to avoid doing that or is it ok as is?

The code is ok as is, but I would refactor it to use hooks :slight_smile: