React:如何更新具有可变值和不可变值的状态

时间:2017-10-17 22:36:53

标签: javascript reactjs immutability

在Javascript中,string, integer and boolean values are immutable, but objects and arrays are mutable.

如果状态具有两种类型的值,我们应该如何更新React中的状态?

e.g。

constructor(props) {
    super(props);
    this.state = {
        success: false,
        error: false,
        errorMessages: {}
    };
}

假设您需要立即更新所有属性(successerrorerrorMessages),最好的方法是什么?

至少我确定errorMessages不应该直接更新,因为它本质上是可变的,但其余的呢?

我尝试了类似下面的内容,但结果却是错误的结果。

const errorMessages = {
    ...this.state,
    "errorMessages": error.response.data,
};

this.setState({
    errorMessages,
    success: false,
    error: true,
});

//The errorMessages property will have "success" and "error" property in it

3 个答案:

答案 0 :(得分:3)

只要您为errorMessages提供新值,React就会正确更新状态。你不是在这里直接改变状态,你只是为该字段提供一个新值,React将进行必要的变异:

this.setState({
   errorMessages: error.response.data
   success: false,
   error: true,
});

答案 1 :(得分:3)

所以假设你的州最初是

this.state = {
    success: false,
    error: false,
    errorMessages: {}
};

然后为errorMessages创建一个新对象

const errorMessages = {
    ...this.state,
    "errorMessages": error.response.data,
};

this.setState({
    errorMessages,
    success: false,
    error: true,
});

然后,你的下一个状态将会是这样的,我不确定这是否是你想要的

{
   errorMesages: {
     success: false,
     error: true,
     errorMessages: {
       // content of the error.response.data
     }
   },
   success: false,
   error: true
}

您可能想直接分配新状态,实际上是您创建的errorMessages const,您只是在执行它;)

之所以如此,是因为在没有值的情况下向对象添加变量时,jcc会自动将标签命名为变量,例如:

const a = 10;
const b = {
  a
};

// result in: { a: 10 };
console.log(b);

答案 2 :(得分:0)

有三种更新状态的方法:

this.setState({
    success: !this.state.success,
    error: !this.state.error,
    errorMessages: delete this.state.id // if id were a prop in errorMessages
})

this.setState((prevState) => {
  return {
    success: !prevState.success,
    error: !prevState.error,
    errorMessages
  }
});

this.setState((prevState) => {
  return {
    success: !prevState.success,
    error: !prevState.error,
    errorMessages
  }
}, () => { // some callback function to execute after setState completes })