React使用useState管理数组时无法按指定索引删除对应元素问题求助
问题根源
你代码的核心错误是子组件内混淆了单个数组元素和完整列表数组:
父组件传递给子组件的item是当前行的单个元素值(比如你提到的ss、77这类字符串),并不是整个items状态数组。你在removeItem方法里执行[...item]相当于把字符串拆成了单个字符组成的数组,后续的splice操作全是基于这个拆分后的字符数组执行,最后调用setItem直接把父组件的整个列表替换成了这个错误的字符数组,才会出现改内容、误删其余元素、清空数组的异常表现。
另外还有两个次要问题:
- 父组件
map渲染列表时没有加唯一key属性,会导致React列表渲染异常 - 父组件
map的回调参数名和外层状态items重名,容易引发变量混淆 - 子组件内把HTML属性
class写为className才符合React语法规范
修正后代码
父组件
const Pagethree = () => { const [items, setItem] = useState([]); return( <ul> { // 修改参数名避免和外层state重名,新增key属性 items.map((item, i) => <ListItem key={i} index={i} item={item} setItem={setItem}/> ) } </ul> ) }
子组件
import React from "react"; const ListItem = (props) =>{ const {item, setItem, index} = props; const removeItem = () =>{ // 基于原有完整数组过滤掉对应下标的项,符合React不可变数据原则 setItem(prevItems => prevItems.filter((_, i) => i !== index)); } return( <div> <div className="flex"> {item} <button onClick={removeItem}>delete</button> </div> </div> ) }; export default ListItem;
补充说明
用filter代替splice是更推荐的写法,不需要手动拷贝数组,也不会意外修改原数据,能避免很多奇怪的状态异常。
内容的提问来源于stack exchange,提问作者jgrewal
相关产品推荐
相关产品推荐

