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

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)
}

其他回答

我用reduce搜索做嵌套更新:

例子:

状态中的嵌套变量:

state = {
    coords: {
        x: 0,
        y: 0,
        z: 0
    }
}

功能:

handleChange = nestedAttr => event => {
  const { target: { value } } = event;
  const attrs = nestedAttr.split('.');

  let stateVar = this.state[attrs[0]];
  if(attrs.length>1)
    attrs.reduce((a,b,index,arr)=>{
      if(index==arr.length-1)
        a[b] = value;
      else if(a[b]!=null)
        return a[b]
      else
        return a;
    },stateVar);
  else
    stateVar = value;

  this.setState({[attrs[0]]: stateVar})
}

Use:

<input
value={this.state.coords.x}
onChange={this.handleTextChange('coords.x')}
/>

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

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

this.setState({})

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

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

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

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

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

我发现这对我很有用,在我的案例中有一个项目表单,例如,你有一个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>
)

让我知道!

There is another option and this works if there are multiple items in the list of objects: copy the object using this.state.Obj to a variable (say temp), use filter() method to traverse through the object and grab the particular element you want to change into one object(name it updateObj) and the remaining list of object into another object(name this as restObj). Now edit the contents of object you want to update creating a new item (say newItem). Then call this.setUpdate() and use spread operators to assing new list of objects to the parent object.

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


var temp=[...this.state.someProperty]
var restObj = temp.filter((item) => item.flag !== true);
var updateObj = temp.filter((item) => item.flag === true);

var newItem = {
  flag: false
};
this.setState({ someProperty: [...restObj, newItem] });