我想根据 id
等于传递的 prop 来删除嵌套对象。此刻,整个对象被替换。当尝试使用 useState 更新状态时,我可能遗漏了一些东西,可能是我循环对象的方式?
更新:该问题已针对可用的 answers 关闭用于更新嵌套对象。这个问题涉及数组,我认为这是当前问题的一部分。请注意此问题与 forEach
本质上的区别。也许需要一个 return
语句,或者使用不同的方法来过滤 id..
我的初始对象如下所示:
{
"some_id1": [
{
"id": 93979,
// MORE STUFF
},
{
"id": 93978,
// MORE STUFF
}
],
"some_id2": [
{
"id": 93961,
// MORE STUFF
},
{
"id": 93960,
// MORE STUFF
}
]
}
我会这样浏览每个项目:
for (const key in items) {
if (Object.hasOwnProperty.call(items, key)) {
const element = items[key];
element.forEach(x => {
if (x.id === singleItem.id) {
setItems(prevState => ({
...prevState,
[key]: {
...prevState[key],
[x.id]: undefined
}
}))
}
})
}
最佳答案
您的代码中有 3 个问题:
- 您将
key
的值设置为一个对象,而items
预计具有一个 ids 数组。
// current
[key]: {
...prevState[key],
[x.id]: undefined
}
// expected
[key]: prevState[key].filter(item => item.id === matchingId)
- 如果您打算根据某些条件从数组中删除对象,则应该使用
filter
,如 Owen 的 answer 中指出的那样。因为你正在做的事情是别的事情:
const a = { xyz: 123, xyz: undefined };
console.log(a); // { xyz: undefined} - it did not remove the key
为了使代码更具可读性,需要操作整个对象
items
,然后使用setItems
将其设置为状态 - 相比之下根据某些条件在循环内多次调用setItems
。这使您的代码更具可预测性并减少重新渲染。
另外,您的问题的解决方案:
// Define this somewhere
const INITIAL_STATE = {
"some_id1": [
{
"id": 93979
},
{
"id": 93978
}
],
"some_id2": [
{
"id": 93961
},
{
"id": 93960
}
]
};
// State initialization
const [items, setItems] = React.useState(INITIAL_STATE);
// Handler to remove the nested object with matching `id`
const removeByNestedId = (id, items) => {
const keys = Object.keys(items);
const updatedItems = keys.reduce((result, key) => {
const values = items[key];
// Since, we want to remove the object with matching id, we filter out the ones for which the id did not match. This way, the new values will not include the object with id as `id` argument passed.
result[key] = values.filter(nestedItem => nestedItem.id !== id)
return result;
}, {});
setItems(updatedItems);
}
// Usage
removeByNestedId(93961, items);
关于reactjs - 使用 prevState 和 useState 钩子(Hook)更新对象内数组内的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68642687/