我试图通过使用这样的嵌套属性来组织我的状态:

this.state = {
   someProperty: {
      flag:true
   }
}

但是像这样更新状态,

this.setState({ someProperty.flag: false });

是行不通的。怎样才能正确地做到这一点呢?


当前回答

这显然不是正确或最好的方法,但在我看来,这是更清晰的:

this.state.hugeNestedObject = hugeNestedObject; 
this.state.anotherHugeNestedObject = anotherHugeNestedObject; 

this.setState({})

然而,React本身应该迭代思想嵌套对象,并相应地更新状态和DOM。

其他回答

创建一个状态的副本:

let someProperty = JSON.parse(JSON.stringify(this.state.someProperty))

对该对象进行更改:

someProperty.flag = "false"

现在更新状态

this.setState({someProperty})

根据框架的标准,不确定这在技术上是否正确,但有时您只是需要更新嵌套对象。这是我使用钩子的解决方案。

setInputState ({ ... inputState, [括号]:内务部[括号],[childKey]: });

有时候直接回答并不是最好的答案:)

短版:

这段代码

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()中编写一些复杂的逻辑仍然可以解决这个问题,但我宁愿在这里停下来,使用简短版本中的简单解决方案。

如果你正在使用ES2015,你可以访问Object.assign。您可以使用它来更新嵌套对象。

this.setState({
  someProperty: Object.assign({}, this.state.someProperty, {flag: false})
});

您将更新的属性与现有属性合并,并使用返回的对象更新状态。

编辑:将一个空对象作为目标添加到赋值函数中,以确保状态不会像carkod指出的那样直接发生突变。

这是第一个答案的变体,不需要任何额外的包、库或特殊函数。

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对象。