React使用filter删除数组元素时UUID不断变化且删除失效问题
问题根因
你的问题核心出在UUID的生成和存储逻辑错误:
- 你在
map遍历渲染待办项时才调用uuidv4()生成key和id,只要App组件触发重渲染(比如输入框内容变化、新增/删除任务),所有待办项的key和id都会被重新生成,既导致React虚拟DOM比对失效,也让删除逻辑拿不到固定的匹配标识。 - 你的
items状态当前只存了任务文本字符串,并没有存储对应的UUID,删除时用传入的id和任务文本做匹配,逻辑完全不匹配,自然无法正常删除。
修正方案
步骤1:修改新增任务逻辑
新增任务时就生成固定的UUID,每个任务存为包含id和content属性的对象,而非单纯的文本字符串。
步骤2:修改渲染和删除逻辑
渲染时直接用任务自带的固定id作为key和传入子组件的id,不要重新生成UUID;删除时直接匹配任务的id属性即可。
修正后完整App组件代码:
import React, {useState} from "react"; import ToDoItem from "./ToDoItem"; import { v4 as uuidv4 } from 'uuid'; function App() { const [item, setItem] = useState(""); const [items, setItems] = useState([]); function handleChange(event){ const newItem = event.target.value; setItem(newItem); } function addItem(){ if(item.length > 0){ console.log(item + " inserted!"); setItems( (prevItems) =>{ // 新增时生成固定id,存储为对象 return [...prevItems, { id: uuidv4(), content: item }]; }); setItem(""); } } function deleteItem(id){ setItems((prevItems) =>{ // 匹配任务对象的id属性 return prevItems.filter(item => item.id !== id) }); } return ( <div className="container"> <div className="heading"> <h1>To-Do List</h1> </div> <div className="form"> <input type="text" onChange={handleChange} value={item}/> <button onClick={addItem}> <span>Add</span> </button> </div> <div> <ul> { items.map((todoItem) => ( <ToDoItem // 直接用任务自带的固定id,不要重新生成 key={todoItem.id} id={todoItem.id} item={todoItem.content} onDelete={deleteItem} /> ))} </ul> </div> </div> ); } export default App;
说明
ToDoItem组件无需做任何修改,现有逻辑可以正常运行。
内容的提问来源于stack exchange,提问作者Hawanity
相关产品推荐
相关产品推荐

