简体   繁体   English

为什么React中的SetState更新处理程序中的其他对象?

[英]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. 在onChange事件处理程序中,我仅在userTxt上进行setState()调用,但看起来它还设置了颜色对象的状态。 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. 这是我的webpackbin示例的链接。 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

This is happening because you are directly manipulating the state here. 发生这种情况是因为您直接在这里操纵状态。 myColors refers to the state's colors object. myColors引用状态的颜色对象。

  handleMe(e) {
        let myAge = this.state.age;
        let myColors = this.state.colors;

        myAge = myAge + 1;
        //directly mutating the state with these 2 lines.
        myColors['best'] = 'mistyrose';
        myColors['second'] = 'red';

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

You need to make a copy of this.state.colors like let myColors = Object.assign({}, this.state.colors) 您需要制作this.state.colors的副本,例如让myColors = Object.assign({},this.state.colors)

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. 将颜色字段分配给myColors时,两个变量都引用同一对象。 So when you update myColors, the colors field in the state gets updated. 因此,当您更新myColors时,状态中的颜色字段将被更新。

When you assign the age field to myAge, it copies the value of the age field in state to the myAge field. 当您将年龄字段分配给myAge时,它将状态中的年龄字段的值复制到myAge字段。 So when you update myAge, it does not update the state. 因此,当您更新myAge时,它不会更新状态。

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. 声明变量时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM