2017-03-07 59 views
1

我我的状态存储在input,的onChange函数中我做下面通关键对象更新嵌套属性值

input[e.target.name] = e.target.value; 

它的工作,这将有

{"name":"james"}如果我有这样的输入标签

<input name='name' onChange={this.handleChange} defaultValue=""/> 

但是如果我的初始输入状态具有嵌套属性呢?

{ 
    "name": "alice", 
    "hobby": { 
     "outdoor": "hiking", 
     "indoor": "reading" 
    } 
} 

如果我把name属性在输入姓名=“hobby.outdoor”输入状态的对象将是无效的

{"name":"james", "hobby.outdoor":"something"}

+0

“hobby.outdor”是将被设置为道具名称的字符串。点是字符串的一部分,不会被视为代码运算符。 – disstruct

回答

0

这是很多方法来实现你想要的。其中之一就是你可以创造另一个业余爱好者。所以,你的投入会是这样:

<input name='name' onChange={this.handleChange} defaultValue=""/> 
<input name='outdoor' onChange={this.handleHobbyChange} defaultValue=""/> 

然后你就可以更新内部handleHobbyChange

input.hobby[e.target.name] = event.target.value 

另一种方式的爱好是,你可以通过正则表达式或String.prototype.split解析hobby.outdoor,但我不会推荐这办法。

如果你有许多嵌套的输入来处理,你可以使处理程序成为一个更高阶的函数(一个函数创建一个函数)。例如:

const handle = (inputName) => (e) => { 
    input[inputName][e.target.name] = e.target.value // or use setState here 
} 

而且使用它像

<input name='outdoor' onChange={this.handle('hobby')} defaultValue=""/> 
+0

想象你有很多输入,你必须创建多少自定义处理程序? –

+0

@AlexYong我已经更新了答案。感谢您的询问。 – wuct

1

可以使用setState像这样的:

var state = { 
    hobby: { 
     outdoor: null 
    } 
}; 

function setState(target, value) { 
    var parts = target.split('.'); 
    parts.reduce(function (res, p, i) { 
     return i === parts.length - 1 ? (res[p] = value) : res[p]; 
    }, state); 
} 

setState('hobby.outdoor', 'smoking') 
+0

为什么需要检查长度? –

+0

这是要知道什么时候设置的值(而不是进一步下去的道具层次结构) – m1kael