React - 状态数组删除指定索引项时删除的是数组的最后一项

5

我有一个名为state的数组,其中装满了名为items的对象:

    const [items, setItems] = useState([{name: "", toppings: []}])

然而,当我尝试使用此函数删除指定索引时:
const removeItem = (index) => {
    setItems(items.filter((item, i) => i !== index))
    areItemsCompleted()
}

当我在函数外部将元素打印到控制台时,它可以正常工作,但是项目渲染不正确。 它只从jsx中删除数组的最后一个元素,但items数组的值是正确的。 我曾经在某个地方读到,React仅浅层检查状态变化,因此它不会检查要删除的对象的内容。 但是,我不确定为什么控制台显示items具有正确的值,但组件没有呈现正确的数据。 (相反,它呈现相同的数据,除了items中的最后一个元素。)

我尝试了多种方法来从我的数组中删除元素,例如:

const removeItem = (index) => {
    let arr = [...items]
    arr.splice(index, 1)
    setItems(arr)
    areItemsCompleted()
}

我如何从对象数组中删除一个元素并呈现正确的数据?

能否提供一个最小问题的工作沙盒演示?我认为这里有太多的事情需要自动知道解决方案——也就是说,也许是setItems()出了问题,而filter()运行正常?我不确定,但一个沙盒会有所帮助。 - HoldOffHunger
3
听起来你正在将数组索引用作映射 JSX 的“key”。 - Brian Thompson
2个回答

4

所以我之前把数组索引用作组件的key属性,但是在删除数组中的一个元素时,这种方式就不起作用了。

React不知道删除哪个键,因为即使删除了特定的元素,数组索引仍将存在。

解决方法

为数组中的每个元素使用唯一的键。比如id,这样React就可以看到已经被删除了。


1
这个解决方案解决了我的问题。 我为每个项目生成了一个 id(使用 Math.random())并将其设置为 key - Frank Wang

2

很难猜测;

检查一下,也许你在后面某个地方重新设置了项目;

此外,函数形式更安全: setItems(lastItems=>lastItems.filter((item, i) => i !== index))


我刚刚检查了一下,因为该方法中唯一的其他函数是更改不同状态,所以我没有在其他地方重新设置状态。我尝试了上面的代码,但可悲的是它并没有起作用。(它在控制台中给出了正确的输出,但仍未呈现组件) - Stuart Fong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接