包含嵌套对象的 setState 的最佳方法是什么
what is the best way to setState which contains nested Object
我有一个包含多个字段的表单。
为了处理我正在使用受控组件的状态。
我使用的方法如下所示。
这最初是有效的,但随着需求的变化,我不得不使用嵌套对象来定义初始状态。
handleChange
不再正常工作。
我怎样才能为嵌套对象实现相同的结果。
const [details, setDetails] = useState({
description: null,
platform: "Xbox",
region: "ASIA",
time:{
start: "2017-05-24T10:30",
end: "2017-05-28T10:30",
},
contact: {
email: "",
phone: "",
twitter: "",
discord: "",
}
});
function handleChange(evt) {
const value = evt.target.value;
setDetails({
...details,
[evt.target.name]: value,
});
}
示例组件
<TextField
label="Description"
onChange={handleChange}
name="description"
value={details.description}
/>
<TextField
label="email"
onChange={handleChange}
name="email"
value={details.contact.email}
/>
contact
中的字段需要其他 handleChange
:
function handleChangeContact(evt) {
const value = evt.target.value;
setDetails({
...details,
contact: {
...details.contact,
[evt.target.name]: value,
}
});
}
<TextField
label="email"
onChange={handleChangeContact}
name="email"
value={details.contact.email}
/>
懒惰的方式,但我会做这样的事情:
function handleNestedChange(key, event) {
setDetails({
...details,
[key]: {
...details[key],
[event.target.name]: event.target.value
}
});
}
<TextField
label="email"
onChange={(e) => handleNestedChange("contact", e)}
name="email"
value={details.contact.email}
/>
您可以像这样更新嵌套对象
<TextField
label="email"
onChange={handleChange}
name="contact_email"
value={details.contact.email}
/>
function handleChange(evt) {
const value = evt.target.value;
const name = evt.target.name.split("_"); // [0: contact, 1: email]
setDetails({ ...details, amount : { ...details[name[0]],
[name[1]]: value }})
}
我认为这样效果最好。
function handleNestedChange(evt) {
const value = evt.target.value;
const keys = evt.target.name.split(".");
if(keys > 1){
setDetails({
...details,
[keys[0]]: {
...details[keys[0]],
[keys[1]]: event.target.value
}
});
}else{
setDetails({
...details,
[keys[0]]: event.target.value
}
});
}
}
<TextField
label="Email"
onChange={handleChange}
name="contact.email"
value={details.description}
/>
此外,如果您开始将巨大的嵌套对象存储到状态中,请查看包 immutability-helper。它使仅更新对象中的特定字段变得更容易,并且比重新创建整个对象更快。
我有一个包含多个字段的表单。
为了处理我正在使用受控组件的状态。
我使用的方法如下所示。
这最初是有效的,但随着需求的变化,我不得不使用嵌套对象来定义初始状态。
handleChange
不再正常工作。
我怎样才能为嵌套对象实现相同的结果。
const [details, setDetails] = useState({
description: null,
platform: "Xbox",
region: "ASIA",
time:{
start: "2017-05-24T10:30",
end: "2017-05-28T10:30",
},
contact: {
email: "",
phone: "",
twitter: "",
discord: "",
}
});
function handleChange(evt) {
const value = evt.target.value;
setDetails({
...details,
[evt.target.name]: value,
});
}
示例组件
<TextField
label="Description"
onChange={handleChange}
name="description"
value={details.description}
/>
<TextField
label="email"
onChange={handleChange}
name="email"
value={details.contact.email}
/>
contact
中的字段需要其他 handleChange
:
function handleChangeContact(evt) {
const value = evt.target.value;
setDetails({
...details,
contact: {
...details.contact,
[evt.target.name]: value,
}
});
}
<TextField
label="email"
onChange={handleChangeContact}
name="email"
value={details.contact.email}
/>
懒惰的方式,但我会做这样的事情:
function handleNestedChange(key, event) {
setDetails({
...details,
[key]: {
...details[key],
[event.target.name]: event.target.value
}
});
}
<TextField
label="email"
onChange={(e) => handleNestedChange("contact", e)}
name="email"
value={details.contact.email}
/>
您可以像这样更新嵌套对象
<TextField
label="email"
onChange={handleChange}
name="contact_email"
value={details.contact.email}
/>
function handleChange(evt) {
const value = evt.target.value;
const name = evt.target.name.split("_"); // [0: contact, 1: email]
setDetails({ ...details, amount : { ...details[name[0]],
[name[1]]: value }})
}
我认为这样效果最好。
function handleNestedChange(evt) {
const value = evt.target.value;
const keys = evt.target.name.split(".");
if(keys > 1){
setDetails({
...details,
[keys[0]]: {
...details[keys[0]],
[keys[1]]: event.target.value
}
});
}else{
setDetails({
...details,
[keys[0]]: event.target.value
}
});
}
}
<TextField
label="Email"
onChange={handleChange}
name="contact.email"
value={details.description}
/>
此外,如果您开始将巨大的嵌套对象存储到状态中,请查看包 immutability-helper。它使仅更新对象中的特定字段变得更容易,并且比重新创建整个对象更快。