嗨,
我正在创建一个表单来创建虚拟机。信息跨多个页面(组件)收集,并集中在顶级组件中。
它的状态对象看起来像这样:
const [vmProp, setVmProp] = useState({
name: "",
image_id: "",
image_name: "",
volumesList: [],
RAM: "",
vcpu: "",
autostart: true,
});
我希望能够向卷列表中添加/删除卷,并且我希望volumeList看起来像这样:
[
{
name: "main",
size: 1024
},
{
name: "backup",
size: 2048
},
{
name: "export",
size: 2048
}
]
目前,我仅尝试添加卷。
const handleAddVolume = (obj) => {
setVmProp({ ...vmProp,
volumesList: {
...vmProp.volumesList,
[obj.name]: {
size: obj.size,
},
} });
};
它正在工作,但是输出是:
[
name: {
size: 1024
}
]
const handleAddVolume = (obj) => {
setVmProp({ ...vmProp,
volumesList: {
...vmProp.volumesList,
{
name: obj.name,
size: obj.size,
},
} });
};
输出:
[
name: "main",
size: 1024
]
您对如何处理此类状态对象有任何想法吗? 谢谢
答案 0 :(得分:1)
如果您不需要从其他状态嵌套/取消嵌套卷列表,则将拥有更好的时间。 (更习惯的做法是为每个值都具有一个状态原子,但是对于简单的值(例如布尔值和字符串),这样做就可以。)
const [vmProps, setVmProps] = useState({
name: "",
image_id: "",
image_name: "",
RAM: "",
vcpu: "",
autostart: true,
});
const [volumesList, setVolumesList] = useState([]);
答案 1 :(得分:1)
volumesList 不应该是对象,而是将其作为 handleAddVolume 函数中的数组。
尝试以下方法,
const handleAddVolume = (obj) => {
setVmProp({ ...vmProp,
volumesList: [
...vmProp.volumesList,
{
name: obj.name,
size: obj.size,
}
] });
};
答案 2 :(得分:0)
这是一个可行的示例:
Set OL = CreateObject("Outlook.Application")
Set OLmail = OL.CreateItemFromTemplate("C:\Users\bhraman\Desktop\VBA practise\Add_picture_table_and_send_mail.msg")
Set Rng = ThisWorkbook.Worksheets("Sheet2").Range("f7:k7")
'Rng.Copy
Rng.CopyPicture
'Set p = ActiveSheet.Pictures.Paste
' p.Cut
With OLmail
.To = "bhraman@deloitte.com"
.Subject = "Test"
Set wordDoc = OLmail.GetInspector.WordEditor
wordDoc.Range.Paste
'.HTMLBody = Replace(OLmail.HTMLBody, "Trw", wordDoc.Range.Paste)
'.display
strbody = "Congratulations on your service anniversary with the team! We look forward to many more successful years with you!.<br><br>"
'.HTMLBody = Replace(OLmail.HTMLBody, "TRW", wordDoc.Range.Paste)
.HTMLBody = Replace(OLmail.HTMLBody, "Trw", strbody & "<br><br>" & p & "Regards,<br>Talent")
'.HTMLBody = .HTMLBody & "<br><br>Best Regards,<br>Talent"
.display
这只是概念的证明。基本上,const Example = (props) => {
const inputRef = createRef();
const [vmProp, setVmProp] = useState({
name: "",
image_id: "",
image_name: "",
volumesList: [],
RAM: "",
vcpu: "",
autostart: true,
});
const { volumesList } = vmProp;
const handleAddVolume = (e) => {
e.preventDefault();
const input = inputRef.current.value;
setVmProp((prevVmProp) => {
const newVmProp = { ...prevVmProp };
newVmProp.volumesList.push({
name: input,
size: 1024,
});
return newVmProp;
});
// reset the input
inputRef.current.value = "";
};
return (
<>
<form>
<input ref={inputRef} type="text" />
<button onClick={handleAddVolume}>Add volume</button>
</form>
{volumesList.map((volume) => (
<div key={volume.name}>{`${volume.name} - ${volume.size}`}</div>
))}
</>
);
};
export default Example;
接受一个函数,该函数获取最新状态值,因为更新是异步的,并返回状态的新值。因此,使用ES6's destructuring函数,我将复制名为setVmProp
的{{1}}最新值,然后将一个新对象推入vmProp
,然后返回{新添加的音量+其他所有内容。我从输入字段获得的newVmProp
的值。同样,这只是概念的证明。
答案 3 :(得分:0)
由于我需要能够添加/删除/替换数组中的对象,因此决定按如下所示创建其自己的状态:
const [volumesList, setVolumesList] = useState([]);
const handleAddVolume = (obj) => {
setVolumesList((oldList) => [...oldList, obj]);
};
const handleRemoveVolume = (obj) => {
setVolumesList((oldList) => oldList.filter((item) => item.name !== obj.name));
};
const handleEditVolume = (obj) => {
setVolumesList(
volumesList.map((volume) =>
(volume.name === obj.name
? { ...volume, ...obj }
: volume),
),
);
};
感谢您的所有回答!