如何在 React 中更新嵌套状态属性
我尝试使用如下嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态
this.setState({ someProperty.flag: false });
不起作用。如何正确完成此操作?
为了对嵌套对象进行
setState
,您可以按照下面的方法,因为我认为 setState 不处理嵌套更新。
var someProperty = {...this.state.someProperty}
someProperty.flag = true;
this.setState({someProperty})
这个想法是创建一个虚拟对象,对其执行操作,然后用更新后的对象替换组件的状态
现在,扩展运算符仅创建对象的一个​​级别嵌套副本。如果您的状态是高度嵌套的,例如:
this.state = {
someProperty: {
someOtherProperty: {
anotherProperty: {
flag: true
}
..
}
...
}
...
}
您可以在每个级别使用扩展运算符设置状态,例如
this.setState(prevState => ({
...prevState,
someProperty: {
...prevState.someProperty,
someOtherProperty: {
...prevState.someProperty.someOtherProperty,
anotherProperty: {
...prevState.someProperty.someOtherProperty.anotherProperty,
flag: false
}
}
}
}))
但是,随着状态变得越来越嵌套,上述语法变得越来越丑陋,因此我建议您使用
immutability-helper
包来更新状态。
有关如何使用
immutability-helper
更新状态,请参阅
此答案
。
用一行写
this.setState({ someProperty: { ...this.state.someProperty, flag: false} });
有时直接的答案并不是最好的答案 :)
简短版本:
此代码
this.state = {
someProperty: {
flag: true
}
}
应简化为类似
this.state = {
somePropertyFlag: true
}
长版本:
目前 您不应该想在 React 中使用嵌套状态 。因为 React 不适用于处理嵌套状态,并且此处提出的所有解决方案看起来都是黑客攻击。他们不使用框架,而是与之抗争。他们建议编写不太清晰的代码,以便对某些属性进行分组的可疑目的。因此,它们作为挑战的答案非常有趣,但实际上毫无用处。
让我们想象以下状态:
{
parent: {
child1: 'value 1',
child2: 'value 2',
...
child100: 'value 100'
}
}
如果您仅更改
child1
的值,会发生什么? React 不会重新渲染视图,因为它使用浅比较,它会发现
parent
属性没有改变。顺便说一句,直接改变状态对象通常被认为是一种不好的做法。
因此,您需要重新创建整个
parent
对象。但在这种情况下,我们会遇到另一个问题。React 会认为所有子项都已更改其值,并将重新渲染所有子项。当然,这对性能不利。
仍然可以通过在
shouldComponentUpdate()
中编写一些复杂的逻辑来解决该问题,但我更愿意在这里停下来并使用简短版本的简单解决方案。