Nikolaos Pavlou Nikolaos Pavlou - 3 years ago 152
React JSX Question

Why is SetState in React updating other objects in handler?

In the onChange event handler, I am only making a setState() call on the userTxt but it looks like it also sets the state of the color object. Whats strange to me is that this is only happening to the color object but not to the age variable.

Was wondering if someone could please explain why this is happening?Here is a link to my webpackbin example. As you write in the input, the state is changed on the color object..

I was hoping someone could please explain to me the mechanics of why this is happening. Thank you very much in advance.

import React, { Component } from 'react';

export default class Hello extends Component {

constructor() {
super();
this.handleMe = this.handleMe.bind(this);
this.state = {
age: 21,
colors: {
best: 'blue',
second: 'green'
},
userTxt: ""
}
}
handleMe(e) {
let myAge = this.state.age;
let myColors = this.state.colors;

myAge = myAge + 1;
myColors['best'] = 'mistyrose';
myColors['second'] = 'red';

this.setState({ userTxt: e.target.value });
}

render() {
const { age, colors, userTxt} = this.state;
return (
<div>
<form action="">
<input type="text"onChange={this.handleMe}/>
<div>Age: {age}</div>
<div>Colors - best: {colors.best}</div>
<div>Colors - second: {colors.second}</div>
<div>UserTxt: {userTxt}</div>
</form>
</div>
)
}
}[enter link description here][1]


[1]: https://www.webpackbin.com/bins/-KvFx-s7PpQMxLH0kg7m

Answer Source

The colors field in the state is an object which is stored as a reference. The age field is a integer and is stored as a primitive value.

When you assign the color field to myColors, both variables reference the same object. So when you update myColors, the colors field in the state gets updated.

When you assign the age field to myAge, it copies the value of the age field in state to the myAge field. So when you update myAge, it does not update the state.

More on this at Primitive value vs Reference value

To prevent this unintended side effect, you should create a new object and copy the values of colors from the state to it. You can do this by using

let myColors = {...this.state.colors};

when declaring the variable.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download