在reactjs状态下通过数组表示法更新嵌套对象值

时间:2018-04-30 11:37:26

标签: javascript reactjs ecmascript-6

我有一些尝试更新特定状态的通用代码。可以通过数组中的键访问对象,例如:

let x = {person: { name: "Dennis"}} 
console.log(x["person"]["name"])

在反应中,可以(通常用于输入验证)通过数组访问特定的状态键,例如:

//event.target.name = input field property name="firstName"
this.setState({
    [event.target.name]: event.target.value
});

this.state.firstName更新为输入值。

我正在尝试将嵌套的复杂对象绑定到输入,以避免具有转换功能。因此,如果我的州包含{ person: {name : "" } },我想通过this.state动态访问它[&#34; person&#34;] [&#34; name&#34;] - 这有效。我想在setState中使用相同的表示法,因为我可以将嵌套的状态数据绑定到这样的输入:<input name="person.name" />并且在我的更改处理程序中我可以查找句点:if(ev.target.name.split("."))...

但是,我似乎无法在setState中以相同的方式访问状态,因为它是一个对象,所以:

const args = ev.target.name.split(".");
this.setState({
    [args[0]][args[1]]: ev.target.value
});

有没有这样做?

3 个答案:

答案 0 :(得分:1)

事实证明这比最初想象的要复杂一些。通过使用Object.assign,所有嵌套对象都保留了它们的不可变属性,这使得无法更改它们。我不得不制作一份国家的硬拷贝,以便改变它。使用lodash.set中的_set可以在很少的行中完成:

//Create a hard-copy of the state
let stateCopy = JSON.parse(JSON.stringify(this.state));

//Update the value in the state with the input value
_set(stateCopy, ev.target.name, ev.target.value);

//Set the state with the changed value
this.setState(stateCopy);

编辑:唯一的缺点是目前我在setState()中复制整个状态而不仅仅是delta值。

答案 1 :(得分:0)

我喜欢使用ramda。 它看起来像

this.setState(R.assocPath(args, ev.target.value))

答案 2 :(得分:0)

它有点复杂,你可以深层复制对象:

 const args = ev.target.name.split(".");
 let result = {};
 const root = result;
 let pos = this.state;
 const last = args.pop();
 for(const arg of args) {
   Object.assign(result, pos);
   result = result[arg] || (result[arg] = {});
   pos = pos[arg] || {};
 }
 result[last] = evt.target.value;
 this.setState(root);