我做了一个基本的应用程序来练习 React,但我很困惑为什么当我尝试从状态数组中删除单个组件时,它之后的所有项目也被删除了。这是我的基本代码:
应用程序.js:
import React from 'react'
import Parent from './Parent';
import './App.css';
function App() {
return (
<div className="App">
<Parent />
</div>
);
}
export default App;
Parent.js:
import React, { useState } from 'react';
import ListItem from './ListItem';
import './App.css';
function Parent() {
const [itemList, setItemList] = useState([])
const [numbers, setNumbers] = useState([])
const addItem = () => {
const id = Math.ceil(Math.random()*10000)
const newItem = <ListItem
id={id}
name={'Item-' + id}
deleteItem={deleteItem}
/>
const list = [...itemList, newItem]
setItemList(list)
};
const deleteItem = (id) => {
let newItemList = itemList;
newItemList = newItemList.filter(item => {
return item.id !== id
})
setItemList(newItemList);
}
const addNumber = () => {
const newNumbers = [...numbers, numbers.length + 1]
setNumbers(newNumbers)
}
const deleteNum = (e) => {
let newNumbers = numbers
newNumbers = newNumbers.filter(n => n !== +e.target.innerHTML)
setNumbers(newNumbers);
}
return (
<div className="Parent">
List of items:
<div>
{itemList}
</div>
<button onClick={addItem}>
Add item
</button>
<div>
List of numbers:
<div>
{numbers.map(num => (
<div onClick={deleteNum}>{num}</div>
))}
</div>
</div>
<button onClick={addNumber}>
Add number
</button>
</div>
);
};
export default Parent;
ListItem.js:
import React from 'react';
import './App.css';
function ListItem(props) {
const { id, name, deleteItem } = props;
const handleDeleteItem = () => {
deleteItem(id);
}
return (
<div className="ListItem" onClick={handleDeleteItem}>
<div>{name}</div>
</div>
);
};
export default ListItem;
- 当我通过单击按钮添加项目时,父状态会正确更新。
- 当我单击该项目(将其删除)时,它会删除自身以及数组中出现在它之后的所有项目 <-- 不良行为。我只想删除特定项目。
- 我也用数字测试过它(没有创建单独的组件)。这些删除正确 - 只有我点击的个人号码被删除。
据我所知,各个项目组件都保存了一个关于创建它们时父状态值的引用。这对我来说似乎是非常奇怪的行为......
当 itemList 状态数组由单独的组件组成时,如何仅删除单个项目?
谢谢
编辑:根据 Bergi 的指示,我通过将“itemList”状态值转换为对象数组以在列表更改时呈现(和重新呈现)来解决此问题:
const addItem = () => {
const id = Math.ceil(Math.random()*10000);
const newItem = {
id: id,
name: 'Item-' + id,
}
const newList = [...itemList, newItem]
setItemList(newList)
}
...
React.useEffect(() => {
}, [itemList]);
...
<div className="Parent">
List of items:
<div>
{itemList.map(item => {
return (<ListItem
id={item.id}
name={item.name}
deleteItem={deleteItem}
/>);
})}
...
最佳答案
问题是您的 deleteItem
函数是旧 itemList
的闭包,从项目创建的那一刻开始。两种解决方案:
- 使用
setItemList
的回调形式 - 不要在该列表中存储 react 元素,而只是普通对象(您可以将其用作 Prop )并仅在呈现
ListItem< 时传递(最新的)
sdeleteItem
函数
关于javascript - 如何在不删除数组其余部分的情况下从 React 状态数组中删除组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65265839/