我希望能够在React ES6中的表单组件状态中修改一些嵌套数据(对象内的对象)。我目前有一个可行的解决方案,但我觉得它可以更优雅地完成。
我想要修改的状态的形状是:
this.state = {
form: {
address: {},
},
};
我希望能够在address: {}
内添加/编辑数据。我目前的工作解决方案是:
onChange(event) {
const { form } = this.state;
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
name === 'street' || name === 'city'
? this.setState({
form: {
...form,
address: {
...form.address,
[name]: value,
},
},
})
: this.setState({
form: {
...form,
[name]: value,
},
});
}
如何让这个解决方案更优雅?有条件的必要吗?如果我想在同一个表单组件的状态中编辑其他嵌套对象,我该如何使它更具动态性呢?
如果我目前拥有的是正确的轨道,那么如何才能使this.setState()
更加动态化address: {}
?如何使它接受嵌套对象的任何名称,无论它是“地址”还是其他任何名称?
更新
从几分钟前开始,我想出了一个更精简,更有效的解决方案,我实际上比上面提到的更好。这是重构的解决方案:
onChange(event) {
const { form } = this.state;
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
const object = 'address';
name === 'street' || name === 'city'
? (form[object][name] = value)
: (form[name] = value);
this.setState({
form,
});
}
所以使用这个新代码,我怎样才能让它更具动态性?更具体地说,如何根据正在更改的输入更加动态地更改const object = 'address';
的值?
答案 0 :(得分:0)
看看immutability-helper图书馆。它可以将您的代码转换为:
onChange(event) {
const { type, checked, value, name } = event.target;
const updatedValue = type === 'checkbox' ? checked : value;
this.setState(state => {
if (name === 'street' || name === 'city') {
return {
form: update(state.form, {
address: {
[name]: { $set: updatedValue },
},
})
};
}
return {
form: update(state.form, {
[name]: { $set: updatedValue },
}),
}
});
}
或者你甚至可以做到这样的事情:
onChange(event) {
const { type, checked, value, name } = event.target;
const updatedValue = type === 'checkbox' ? checked : value;
const updatedObject = { [name]: { $set: updatedValue } };
this.setState(state => ({
form: update(state.form, (name === 'street' || name === 'city') ? { address: updatedObject } : updatedObject)
}));
}
答案 1 :(得分:0)
有两种方法可以实现“更优雅”,但不能实现相同的功能。首先是提取状态更新程序功能。在你的例子中,我会做这样的事情:
const updateForm = (key, value) => ({form}) => ({ ...form, [key]: value });
const updateAddress = (key, value) => updateForm("address", {...form.address, [key]: value});
onChange(event) {
const { form } = this.state;
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
if (name === 'street' || name === 'city') {
this.setState(updateAddress(name, value));
} else {
this.setState(updateForm(name, value));
}
}
请注意,我使用的setState
版本采用(prevState, props) => { partialState }
形式的函数,并使用解构来从form
传递prevState
setState
1}}