问题描述
我有一组处于反应状态的对象。
[
{
id: 'd8t4gf',title: 'Working on',items: [{ title: 'Item 1' },{ title: 'Item 2' },{ title: 'Item 3' }],},{
id: '8jy8g',title: 'Done',{ title: 'Item 2' }],]
我正在尝试像这样更新第二个对象的项目。
const handleAddNewItemSubmit = (title,id) => {
const listIndex = lists.findindex((list) => list.id === id);
const newData = [...lists];
newData[listIndex].items = [...newData[listIndex].items,{ title }];
setLists(newData);
};
有没有更好的方法来做到这一点?
解决方法
您正在改变现有状态(特别是数组对象 - 例如 lists[0]
),这在 React 中永远不应该完成。你正在做的事情可能碰巧奏效,但这不是一个好方法。
尝试类似这样的方法,将所有内容克隆到嵌套的 items
属性:
const handleAddNewItemSubmit = (title,id) => {
setLists(
lists.map(list => list.id !== id ? list : ({
...list,items: [...list.items,{ title }]
})
);
};
,
const handleAddNewItemSubmit = (title,id) => {
const listIndex = lists.findIndex((list) => list.id === id);
const newData = [...lists];
newData[listIndex].items = [...newData[listIndex].items,{ title }];
setLists(newData);
};
在上面的代码中,当你做 const newData = [...lists]
时,它只是做浅拷贝,即只有顶级引用会不同,但如果有任何嵌套对象,它们将具有与 {{} 相同的引用1}}。
因此,当您执行 lists
时,您实际上指的是同一个对象,即 newData[listIndex].items
。由于 lists[listIndex].items
是一个数组,而它又是一个对象,因此它具有与 newData[listIndex].items
相同的引用。
所以,最终你会改变状态。为了避免这种情况,我们可以通过不同的方式进行状态更新
lists[listIndex].items
下面我模拟了两个例子,一个改变顶级对象,另一个在传播后改变嵌套对象。
const handleAddNewItemSubmit = (title,id) => {
setLists(oldLists => oldLists.map(list =>
list.id === id ? ({
...list,{ title }]
}) : list))
}