dunno
dunno

Reputation: 81

setState doesn't update nested object

In my componentDidUpdate I want to change the state of my nested object but It doesn't work.

I did exactly as I did in componentDidMount and componentWillReceiveProps but still nothing.

Here's my state :

this.state = {
    timer: {
       seconds: 0,
       minutes: 0,
       hours: 0
    },
    counter: 30,
    intervalId : null
}

Here's the code that works :

componentDidMount() {
    const intervalId = setInterval(() => {
        var newTimer = { ...this.state.timer };
        newTimer.seconds++;
        this.setState({ timer : newTimer });
    }, 100);
    this.setState({
        intervalId : intervalId
    });
}

Here's the code that doesn't work :

componentDidUpdate() {
    const { seconds, minutes, hours } = this.state.timer;
    const { counterHit } = this.props;
    const newTimer = { ...this.state.timer };

    if (seconds > 0 && seconds % 30 === 0) { counterHit(); }

    if (seconds >= 60) {
        newTimer.minutes++;
        newTimer.seconds = 0;

        console.log("our new obj : ", newTimer);
        console.log("Before state update: ", this.state.timer);

        this.setState({ timer : newTimer }, () => {
            console.log("After state update: ", this.state.timer);
        });
    } else if (minutes >= 60) {
        newTimer.hours++;
        this.setState({ timer : newTimer } );
    }
}

The console.log()s print the following:

our new obj :  {seconds: 0, minutes: 1, hours: 0}
Before state update:  {seconds: 60, minutes: 0, hours: 0}
After state update:  {seconds: 0, minutes: 0, hours: 0}

As you can see the minutes didn't update.

Upvotes: 2

Views: 150

Answers (1)

Anand Undavia
Anand Undavia

Reputation: 3543

The issue is:

 this.setState({ newTimer });

What that means is:

this.setState({ 
    newTimer: newTimer
});

But because you want to update the timer field, use this:

this.setState({ 
    timer: newTimer
});

Upvotes: 4

Related Questions