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

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

但是像这样更新状态,

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

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


当前回答

stateUpdate = () => {
    let obj = this.state;
    if(this.props.v12_data.values.email) {
      obj.obj_v12.Customer.EmailAddress = this.props.v12_data.values.email
    }
    this.setState(obj)
}

其他回答

还有两个选项没有提到:

如果您有深度嵌套的状态,请考虑是否可以重新构造子对象,使其位于根节点。这使得数据更容易更新。 Redux文档中列出了许多方便的库来处理不可变状态。我推荐Immer,因为它允许您以可变的方式编写代码,但在幕后处理必要的克隆。它还会冻结生成的对象,这样以后就不会意外地改变它。

尽管嵌套并不是处理组件状态的真正方式,但有时对于单层嵌套来说很容易。

对于这样一个州来说

state = {
 contact: {
  phone: '888-888-8888',
  email: 'test@test.com'
 }
 address: {
  street:''
 },
 occupation: {
 }
}

我使用的一个可重用的方法是这样的。

handleChange = (obj) => e => {
  let x = this.state[obj];
  x[e.target.name] = e.target.value;
  this.setState({ [obj]: x });
};

然后为你想要处理的每个嵌套传递obj名称…

<TextField
 name="street"
 onChange={handleChange('address')}
 />

我发现这对我很有用,在我的案例中有一个项目表单,例如,你有一个id和一个名称,我宁愿为一个嵌套的项目维护状态。

return (
  <div>
      <h2>Project Details</h2>
      <form>
        <Input label="ID" group type="number" value={this.state.project.id} onChange={(event) => this.setState({ project: {...this.state.project, id: event.target.value}})} />
        <Input label="Name" group type="text" value={this.state.project.name} onChange={(event) => this.setState({ project: {...this.state.project, name: event.target.value}})} />
      </form> 
  </div>
)

让我知道!

为了为嵌套对象设置setState,你可以遵循下面的方法,因为我认为setState不处理嵌套更新。

var someProperty = {...this.state.someProperty}
someProperty.flag = true;
this.setState({someProperty})

其思想是创建一个虚拟对象,对其执行操作,然后用更新的对象替换组件的状态

现在,展开操作符只创建对象的一层嵌套副本。如果你的状态是高度嵌套的,比如:

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

你可以在每一层使用展开运算符setState

this.setState(prevState => ({
    ...prevState,
    someProperty: {
        ...prevState.someProperty,
        someOtherProperty: {
            ...prevState.someProperty.someOtherProperty, 
            anotherProperty: {
               ...prevState.someProperty.someOtherProperty.anotherProperty,
               flag: false
            }
        }
    }
}))

然而,随着状态嵌套越来越多,上面的语法会变得越来越糟糕,因此我建议你使用不可变性帮助包来更新状态。

关于如何使用immutability-helper更新状态,请参阅此回答。

我用了这个方法。

如果你有一个这样的嵌套状态:

   this.state = {
          formInputs:{
            friendName:{
              value:'',
              isValid:false,
              errorMsg:''
            },
            friendEmail:{
              value:'',
              isValid:false,
              errorMsg:''
            }
}

你可以声明handleChange函数来复制当前状态并重新赋值

handleChange(el) {
    let inputName = el.target.name;
    let inputValue = el.target.value;

    let statusCopy = Object.assign({}, this.state);
    statusCopy.formInputs[inputName].value = inputValue;

    this.setState(statusCopy);
  }

这里是带有事件侦听器的HTML

<input type="text" onChange={this.handleChange} " name="friendName" />