在react中更新嵌套状态

时间:2018-04-18 17:30:10

标签: reactjs object state

大家好我正在尝试更新反应中嵌套对象的状态,我现在正在这样做:

handleChange({target: {id, value}}, type) {
    this.setState(
        state => ({
            dwelling: (Object.assign(state.dwelling, {[id]: {[type]: value}}))
        })
    );
}

它来自表格组:

<FormGroup controlId="spaces">
    <ControlLabel>Dormitorios</ControlLabel>
    <FormControl
        componentClass="select"
        value={dwelling.spaces.dorms}
        placeholder="Seleccione"
        onChange={e => this.handleChange(e, 'dorms')}
    >

问题是当我更新子对象dwelling.spaces.dorms的状态时,但是当我尝试放置另一个属性时,它会替换旧的属性而不是添加:

Dwelling之前:

{
   address: "",
   currency: "",
   price: 0,
   publicationType: "",
   spaces: {
     closets: "",
     dorms: "",
     pools: ""
   },
   subtype: "",
   type: ""
}

onChange for dwelling.spaces.dorms

之后
{
   address: "",
   currency: "",
   price: 0,
   publicationType: "",
   spaces: {
     dorms: "3",
   },
   subtype: "",
   type: ""
}

onChange for dwelling.spaces.closets

之后
{
   address: "",
   currency: "",
   price: 0,
   publicationType: "",
   spaces: {
     closets: "3",
   },
   subtype: "",
   type: ""
}

2 个答案:

答案 0 :(得分:3)

此示例使用ES6扩展运算符来保留旧属性,这相当于Object.assign。

所以发生的事情是你没有保留你的嵌套值。

this.setState({
  dwelling: {
    ...this.state.dwelling,
    [id]: { 
      ...this.state.dwelling[id],
      [type]: value
    }  
  }
});

在您的示例中,您使用新对象覆盖了您的值。请注意下面的粗体文字。

  

住宅:( Object.assign(state.dwelling, {[id]:{[type]:value} })))

在粗体文本中,它专门将一个新对象设置为state.dwelling而不保留旧值。所以我们做的是我们使用ES6扩展运算符来帮助将旧值与新值合并

{ 
  ...this.state.dwelling[id],
  [type]: value
} 

答案 1 :(得分:2)

我将表单状态保留在一个复杂的对象中,并且为了简化代码,我在TextField,Select等引用的“ handleChange”函数中使用了此辅助函数。

#card-icons {
  ion-icon {
    font-size: 30px;
    padding: 10px 5px;
  }
  visibility: hidden;
  float: right;
}
ion-card:hover #card-icons {
  visibility: visible;
}

React-redux / Material-UI示例

export function updateObject(obj, keys, value) {
  let key = keys.shift();
  if (keys.length > 0) {
    let tmp = updateObject(obj[key], keys, value);
    return {...obj, [key]: tmp};
  } else {
    return {...obj, [key]: value};
  }
}