我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
当前回答
const newState = Object.assign({}, this.state);
newState.property.nestedProperty = "new value";
this.setState(newState);
其他回答
把它写在一行里
this.setState({ someProperty: { ...this.state.someProperty, flag: false} });
这是第一个答案的变体,不需要任何额外的包、库或特殊函数。
state = {
someProperty: {
flag: 'string'
}
}
handleChange = (value) => {
const newState = {...this.state.someProperty, flag: value}
this.setState({ someProperty: newState })
}
为了设置特定嵌套字段的状态,您已经设置了整个对象。为此,我创建了一个变量newState,并首先使用ES2015扩展操作符将当前状态的内容扩散到该变量中。然后,我用新值替换了this.state.flag的值(因为我在将当前状态扩展到对象后设置了flag: value,所以当前状态下的flag字段将被覆盖)。然后,我简单地将someProperty的状态设置为newState对象。
有时候直接回答并不是最好的答案:)
短版:
这段代码
this.state = {
someProperty: {
flag: true
}
}
应该简化成这样吗
this.state = {
somePropertyFlag: true
}
长版:
目前你不应该在React中使用嵌套状态。因为React不是面向嵌套状态的,这里提出的所有解决方案看起来都是hack。他们不使用框架,而是与之斗争。他们建议为了分组某些属性的可疑目的而编写不那么清晰的代码。所以它们作为挑战的答案是非常有趣的,但实际上毫无用处。
让我们想象一下下面的状态:
{
parent: {
child1: 'value 1',
child2: 'value 2',
...
child100: 'value 100'
}
}
如果只改变child1的值会发生什么?React不会重新渲染视图,因为它使用浅比较,它会发现父属性没有改变。顺便说一句,直接改变状态对象通常被认为是一种糟糕的做法。
所以你需要重新创建整个父对象。但在这种情况下,我们会遇到另一个问题。React会认为所有的孩子都改变了他们的价值观,并重新渲染所有的孩子。当然,这对性能没有好处。
通过在shouldComponentUpdate()中编写一些复杂的逻辑仍然可以解决这个问题,但我宁愿在这里停下来,使用简短版本中的简单解决方案。
试试下面的代码:
this.setState({ someProperty: {flag: false} });
还有两个选项没有提到:
如果您有深度嵌套的状态,请考虑是否可以重新构造子对象,使其位于根节点。这使得数据更容易更新。 Redux文档中列出了许多方便的库来处理不可变状态。我推荐Immer,因为它允许您以可变的方式编写代码,但在幕后处理必要的克隆。它还会冻结生成的对象,这样以后就不会意外地改变它。