Reputation: 21
Why in such case,
var a={b:1};
Object.assign(a,{b:a.b+2},{b:a.b+4});
console.log(a);
The result of assign
is object
{b: 5}
Rather than
{b: 7}
For the record using this I was trying to explain why value is 1 in below code
// assuming this.state = { value: 0 };
this.setState({ value: this.state.value + 1});
this.setState({ value: this.state.value + 1});
this.setState({ value: this.state.value + 1});
Upvotes: 2
Views: 87
Reputation: 7844
Object.assign
and React's setState
work differently. For Object.assign
, you can think of it as a right-to-left merge of the objects:
Object.assign(a,{b:a.b+2},{b:a.b+4});
Object.assign(a,{b:3},{b:5});
Object.assign(a,{b:5});
However, setState
is a different story. It is an asynchronous operation. In your case, you're simply executing the exact same statement three times:
this.setState({ value: 0 + 1});
this.setState({ value: 0 + 1});
this.setState({ value: 0 + 1});
Multiple setState
calls can update state in one event loop and result in a single re-render. Part of the architectural efficiency behind the way setState
works may be responsible for this behaviour. This reference may also be helpful:
Why is setState giving me the wrong value?
If you want to use the previous value of a setState
operation, you can do somthing like this:
setState((prevState) => ({ value: prevState.value + 1 }));
or
setState({ value: this.state.value + 1 }, () => {
// In here, the state has been updated
});
However, it's hard to give a precise practical solution as your example is contrived and there would probably be no practical need to do sequential setState
operations like that.
See the React documentation for more details on setState
.
Upvotes: 0
Reputation: 2007
It's expected a result.
Because of Object.assign not sum values, but overwrite. It set values from right to left. The right value is {b: a.b+4} => {b: 5}
. This value overlapse other ones.
Upvotes: 0
Reputation: 664599
Because arguments are evaluated before being passed to the function. You're basically doing
var a = {b: 1},
tmp1 = {b: a.b+2}, // {b: 1+2}
tmp2 = {b: a.b+4}; // {b: 1+4}
Object.assign(a, tmp1, tmp2);
You would need to do
var a = {b: 1};
Object.assign(a, {b: a.b+2}); // simpler: a.b += 2
Object.assign(a, {b: a.b+4}); // simpler: a.b += 4
to get 7
.
Upvotes: 4