React Todo List删除功能异常:点击删除仅保留最后一项
问题分析与解决
你的删除功能异常的核心问题出在removeItem方法的实现上:
- 你当前通过
map遍历数组,每找到一个不需要删除的项就调用addVal更新state。但React的state更新是异步批量处理的,每次调用addVal都会把数组替换成只包含当前遍历到的项,循环结束后最后一次更新会覆盖所有之前的操作,所以最终只剩最后一个符合条件的项。 - 另外,
[ [...value] ]这种写法完全错误,value是数组中的字符串项,展开后还是字符串,再套数组会变成["单个字符串"],进一步破坏数据结构。
修正后的删除逻辑
正确的做法是先通过filter过滤掉需要删除的项,然后一次性更新state,同时使用函数式更新(依赖prevState)确保拿到最新的数组状态:
let removeItem = (par) => { addVal(prevVal => prevVal.filter((_, index) => index !== par)); };
完整修正代码
import { useState } from 'react'; import './App.css'; let App = () => { const [initial, addInitial] = useState(''); const [val, addVal] = useState([]); let changeHandler = (e) => { addInitial(e.target.value); }; let addItem = (event) => { if (!initial.trim()) return; // 避免添加空项 addVal(prevValues => [...prevValues, initial]); addInitial(''); // 添加后清空输入框 }; let removeItem = (par) => { addVal(prevVal => prevVal.filter((_, index) => index !== par)); }; return ( <div id="parent"> <div id="container"> <h1>To-Do List</h1> <div id="sub1"> <input type="text" value={initial} onChange={changeHandler} placeholder='Add a item' autoFocus /> <button id="add" onClick={addItem}>+</button> </div> <div id="sub2"> {val.map((name, index) => { return ( <div id="cross" key={index}> {/* 注意:如果项可能重复,建议用唯一ID当key */} <button className="remove" onClick={() => removeItem(index)}>❌</button> {name} </div> ); })} </div> </div> </div> ); }; export default App;
额外优化建议
- 添加项后清空输入框,提升用户体验
- 避免添加空项(通过
trim()判断) - 尽量不要用数组index作为
key,如果后续有排序、修改项的操作,会导致渲染异常,建议给每个todo项生成唯一ID(比如用Date.now()或者uuid库)
内容的提问来源于stack exchange,提问作者Anas
相关产品推荐
相关产品推荐

