有多种方法可以做到这一点,因为状态更新是异步操作 https://stackoverflow.com/questions/42593202/why-calling-setstate-method-doesnt-mutate-the-state-immediately/42593250#42593250,所以要更新状态对象,我们需要使用更新功能 https://reactjs.org/docs/react-component.html#setstate with setState
.
1-最简单的一个:
首先创建一个副本jasper
然后进行以下更改:
this.setState(prevState => {
let jasper = Object.assign({}, prevState.jasper); // creating copy of state variable jasper
jasper.name = 'someothername'; // update the name property, assign a new value
return { jasper }; // return new object jasper object
})
而不是使用Object.assign
我们也可以这样写:
let jasper = { ...prevState.jasper };
2- 使用扩展语法 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator:
this.setState(prevState => ({
jasper: { // object that we want to update
...prevState.jasper, // keep all other key-value pairs
name: 'something' // update the value of specific key
}
}))
Note: Object.assign
and Spread Operator
只创造浅拷贝 https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language,因此如果您定义了嵌套对象或对象数组,则需要不同的方法。
更新嵌套状态对象:
假设您将状态定义为:
this.state = {
food: {
sandwich: {
capsicum: true,
crackers: true,
mayonnaise: true
},
pizza: {
jalapeno: true,
extraCheese: false
}
}
}
更新披萨对象的 extraCheese:
this.setState(prevState => ({
food: {
...prevState.food, // copy all other key-value pairs of food object
pizza: { // specific object of food object
...prevState.food.pizza, // copy all pizza key-value pairs
extraCheese: true // update value of specific key
}
}
}))
更新对象数组:
假设您有一个待办事项应用程序,并且您正在以这种形式管理数据:
this.state = {
todoItems: [
{
name: 'Learn React Basics',
status: 'pending'
}, {
name: 'Check Codebase',
status: 'pending'
}
]
}
要更新任何待办事项对象的状态,请在数组上运行映射并检查每个对象的某些唯一值,以防出现以下情况condition=true
,返回具有更新值的新对象,否则返回相同的对象。
let key = 2;
this.setState(prevState => ({
todoItems: prevState.todoItems.map(
el => el.key === key? { ...el, status: 'done' }: el
)
}))
建议:如果对象没有唯一值,则使用数组索引。