我有一个对象数组。我需要添加一个函数来从我的数组中删除一个对象,而不使用“this”关键字。
我试着使用updateList(list.slice(list.indexOf(e.target.name, 1)))
。这会删除数组中的所有内容,只保留最后一项,我不确定为什么。
const defaultList = [
{ name: "ItemOne" },
{ name: "ItemTwo" },
{ name: "ItemThree" }]
const [list, updateList] = useState(defaultList);
const handleRemoveItem = e => {
updateList(list.slice(list.indexOf(e.target.name, 1)))
}
return (
{list.map(item => {
return (
<>
<span onClick={handleRemoveItem}>x </span>
<span>{item.name}</span>
</>
)}
}
)
预期:单击的项目将从列表中删除。
ACTUAL:整个列表被删除,减去数组中的最后一项。
提前感谢您的任何意见!
8条答案
按热度按时间ruarlubt1#
首先,带有click事件的
span
元素需要有一个name
属性,否则,在e.target
中将找不到name。也就是说,e.target.name
是为表单元素(input、select等)保留的。因此,要真正使用name属性,您必须使用e.target.getAttribute("name")
另外,因为你有一个对象数组,所以使用
list.indexOf(e.target.name)
并不有效,因为当你迭代对象时,它会寻找一个string
。最后,
array.slice()
返回一个新的数组**,该数组从您传递给它的索引**处的项开始。因此,如果您单击最后一项,您将只返回最后一项。请尝试使用
.filter()
执行类似以下操作:codesandbox3pvhb19x2#
您可以使用Array.filter在一行程序中完成此操作:
Eta:您还需要在onClick处理程序中传递项目的名称:
bttbmeg03#
hjzp0vay4#
在我看来,到目前为止最好的答案有了小的改进
我们只是将其发送到句柄函数,而不是给出name属性
w46czmvw5#
我想这个代码可以
我们需要检查对象内部的名称值,所以使用findIndex代替。然后将对象从目标索引开始剪切到目标索引后的1个数组。
Codepen
从你的评论来看,你的问题来自另一个部分。
更改此视图节
更改函数handleRemoveItem格式
bwleehnv6#
冗余的一个内衬-不推荐,因为难以测试/定型/扩展/重复/原因
无导出的版本:
然而,我会考虑通过在另一个文件中使用帮助器函数来以不同的方式扩展逻辑结构。
考虑到这一点,我为filter和slice分别做了一个例子。我个人很喜欢这个用例中的slice选项,因为它使它更容易推理。显然,如果缩放,它在更大的列表上也稍微更有表现(参见参考资料)。
如果使用切片,请始终使用切片而不是拼接,除非您有充分的理由不这样做,因为它遵循功能样式(纯功能,没有副作用)
示例(导入时同时使用过滤器选项与切片选项)
参考文献:
oxf4rvwz7#
使用此模式,数组不会跳转,但我们会获取以前的数据,创建新数据并返回。
6pp0gazn8#
这是因为slice和splice都会传回包含已移除元素的数组。
您需要对数组应用
splice
,然后使用钩子提供的方法更新状态