javascript - 在反应中从状态数组中删除项目
问题描述
我有一个如下所示的删除功能:
this.deleteItem = item => event => {
const { res, selectedItems } = this.state;
res.splice(res.indexOf(item), 1);
selectedItems.splice(res.indexOf(item), 1);
this.setState({
res
});
};
这里,res
是页面上显示的项目selectedItems
的列表,是选择了哪些项目的列表。删除项目时res
,selectedItems
应更新以从列表中删除该项目的索引。
但是,每当我尝试删除特定项目时,它只会删除添加到数组中的最后一个项目,而不是与单击的目标索引对应的项目。它被编入索引的方式肯定有问题,但我一直无法确定来源。
我也尝试过这里引用,但这不起作用,因为我需要将item
其作为参数。
什么是解决这个问题的好方法?
非常感谢。
编辑:将函数更改为看起来像@HMK 的响应。删除一个项目后,console.log(res)
render 方法中的输出是一个对象数组,其形式如下:
res
(9) […]
0: Object { id: 0, name: "a", description: "description of a", … }
1: Object { id: 2, name: "b", description: "description of b", … }
2: Object { id: 3, name: "c", description: "description of c", … }
3: Object { id: 4, name: "d", description: "description of d", … }
4: Object { id: 5, name: "e", description: "description of e", … }
5: Object { id: 6, name: "f", description: "description of f", … }
6: Object { id: 7, name: "g", description: "description of g", … }
7: Object { id: 8, name: "h", description: "description of h", … }
8: Object { id: 9, name: "i", description: "description of i", … }
length: 9
<prototype>: Array []
console.log(JSON.stringify(item,undefined,2));
函数中的输出deleteItem
是从数组中删除的对象。
例如:
{
"id": 10,
"name": "j",
"description": "description of j",
"icon": "jIcon",
"selected": false
}
当页面上的所有项目都被选中时,输出console.log("selecteditems:", JSON.stringify(selectedItems))
:
selecteditems: [0,1,2,3,4,5,6,7,8,9,10]
解决方案
要从数组中取出一个项目,您可以执行以下操作:
array.filter(item=>item!==itemToRemove)
所以在你的例子中:
this.deleteItem = item => event => {
const filter = getter => val => getter(val) !== item.id
this.setState({
res: this.state.res.filter(filter(({id})=>id)),
selectedItems: this.state.selectedItems.filter(
filter(id=>id)
)
})
}
您遇到的问题是 res 存储了一个具有 id 的对象数组(例如:[{id:1}]
,然后 selectedItems 是一个存储 id 的数组:(例如:[1])。
Array.prototype.filter 的工作方式如下:newArray = array.filter(filterFunction)
. 对于数组 filterFunction 中的每个项目,都会使用该项目调用该项目。如果 filterFunction 返回false
,则该项目没有被复制到newArray
,它返回 true 它被复制到 newArray。原始数组保持不变(因为它应该是状态,因为你不应该改变它)。
所以问题是您的过滤器函数获取数组的一个项目,决定它是否应该返回真或假(真保留该项目,假不保留它)。因此,如果我过滤res
过滤器函数将接收{id:X}
(带有 id 的对象),但当我过滤时,selectedItems
我将收到X
(id)。
因此,过滤器函数需要取出具有特定 id 的元素;带有res
该 id 的是对象的属性,带有selectedItems
它的是 id。因为res
您可以编写一个 getter 函数来从对象中获取 id: resItem=>resItem.id
,给该函数一个项目 from res
,它会返回一个 id。对于selectedItems
getter 函数应该只返回它给出的值,因为其中的项目selectedItems
是ids,所以 getter 函数看起来像id=>id
好的,让我们回到过滤器,我有一个名为selectedItems
[9] 的 id 数组,并且想要删除值为 9 的 id,让我们称之为 idToRemove 以便我可以这样做:selectedItems.filter(id=>id!==idToRemove)
。相同的功能将无法使用,res
因为{id:9}
never equals 9
。
但是如果我将选择器传递给过滤器函数,这里会变得有点复杂,因为函数可以返回一个函数:
const idToRemove = 9;
//filter function return true for array item to stay in the copied array
// and false to not include the array item in the copy
const filter = getter => arrayItem =>
getter(arrayItem) !== idToRemove;
//passing filter a getter function will return a function that takes
// an item and uses the getter function on that item to compare it
// to idToRemove
const compareId = filter(id => id);
console.log('keep 9?', compareId(9));
console.log('keep 8?', compareId(8));
//now create a filter function that takes an object and uses
// the getter to get object.id and compares that to idToRemove
const compareObjectWithId = filter(object => object.id);
console.log('keep {id:9}?', compareObjectWithId({ id: 9 }));
console.log('keep {id:8}?', compareObjectWithId({ id: 8 }));
我们compareId
可以用来从中过滤出一个项目的函数也是一个函数,我们可以用来从中过滤出一个项目selectedItems
的compareObjectWithId
函数res
是如何使用过滤器的:
const idToRemove = 9;
const createFilterFunction = getter => arrayItem =>
getter(arrayItem) !== idToRemove;
console.log(
'[2,9] remove id 9',
[2, 9].filter(createFilterFunction(id => id))
);
console.log(
'[{id:2},{id:9}] remove id 9',
[{ id: 2 }, { id: 9 }].filter(
createFilterFunction(object => object.id)
)
);
为了完成,我将添加现代代码以从对象中删除键(不要在堆栈溢出代码片段上尝试此操作,因为它使用的是古老的 babel 版本)
const org = {a:1,b:2};
const withoutA = Object.fromEntries(
Object.entries(org).filter(([key])=>key!=='a')//removed key 'a'
)
推荐阅读
- gdb - 如何在不向应用程序传递信号的情况下进行步进?
- docker - 如何将项目代码从 docker 提取到本地系统
- .net - 将权限属性添加到 Swashbucke-Swagger-Documentation
- azure-container-service - 将现有 Web 应用程序移植到 Azure Service Fabric Mesh
- solr - Solr:尽管在 fieldType 上为用于 Faceting 的字段启用 docValues="true",但使用大量内存的字段缓存
- elasticsearch - elasticsearch-dsl 库中不存在 matrix_stats
- c++ - C ++双重充当浮点数?
- stripe-payments - 如何获得条带连接帐户的总支出?
- c++ - C++什么时候进行深拷贝和浅拷贝?
- java - SPNEGO - 从身份验证检查中排除特定 URL/URL 模式