[英]How to elegantly modify nested data within a form component's state in React ES6?
我希望能夠在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';
更動態地取決於正在更改的輸入?
看一看不變性幫助程序庫。 它可以將您的代碼變成:
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)
}));
}
有兩種方法可以實現“更優雅”的功能,但不能實現同一功能。 第一件事是提取狀態更新程序功能。 在您的示例中,我將執行以下操作:
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 }
函數,並使用解構從setState
傳遞的prevState
form
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.