Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react state extend multilevel object not working

state default values

state = {
        moveType: {
            value: 0,
            open: false,
            completed: false
        }
    };

// callback to update new state

let step = 'moveType';
let val = 3; // new value
let newObj = { ...this.state[step], value: val };
console.log(newObj);
this.setState({[step]: newObj }, function () {console.log(this.state);});

console.log(newObj) shows new values proper, but this.state still shows old values.. can you tell me what i'm doing wrong?

like image 588
Basit Avatar asked Feb 05 '26 17:02

Basit


1 Answers

Setting state in react is pretty sensitive thing to do. The best practices I've used to is always control object deep merge manually and use this.setState(state => { ... return new state; }) type of call, like in this example:

this.setState(state => ({
  ...state,
  [step]: { ...(state[step] || {}), ...newObj },
}), () => console.log(this.state));

SNIPPET UPDATE start

[step]: { ...state[step], ...newObj }

Changed to:

[step]: { ...(state[step] || {}), ...newObj }

To deal correctly with cases, when state does not have this step key yet

SNIPPET UPDATE end

Thing is, that when you use this.state (in let newObj = { ...this.state[step]), it might have an outdated value, due to some pending (not merged yet) changes to the state, that you've called just couple of milliseconds ago.

Thus I recommend to use callback approach: this.setState(state => { ... use state and return new state;}) which guarantees that the state you use has latest value

like image 172
Jevgeni Avatar answered Feb 07 '26 07:02

Jevgeni



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!