React中实现点击元素仅删除自身的问题及解决方案
React 删除元素异常问题修复
问题根源
- 状态存储错误:直接把React元素存在
dataList里,而非纯数据对象。React状态该存数据源,渲染时再转成JSX,不然会导致元素key匹配混乱,控制台打印的key不对。 - 初始ID重复生成:组件每次渲染都会执行
const id = UtilsGetID();,初始元素的key会被篡改,没法正确对应。 - 直接修改原数组:用
splice改原状态数组,再扩展赋值,这种操作会让状态更新出问题,导致批量删除。 - 事件传递不可靠:通过
data-key取ID,碰到点击子元素时e.target不是绑定事件的div,就会拿到错误的key。
修正后的代码
import { useState } from 'react'; const UtilsGetID = () => { return Math.random().toString().slice(-8); }; const Demo = () => { // 状态存纯数据对象,不是JSX const [dataList, setDataList] = useState([ { id: UtilsGetID(), content: 'xxx' } ]); const handleDel = (targetId) => { // 用filter生成新数组,不碰原状态 setDataList(prevList => prevList.filter(item => item.id !== targetId)); }; const addCard = () => { const newId = UtilsGetID(); // 函数式更新拿最新状态 setDataList(prevList => [...prevList, { id: newId, content: 'xxx' }]); }; return ( <> <button onClick={addCard}>addNewEle</button> {/* 渲染时根据数据生成JSX,直接传id给删除函数 */} {dataList.map((item) => ( <div key={item.id} onClick={() => handleDel(item.id)} > {item.content},{item.id} </div> ))} </> ); }; export default Demo;
核心修改点
- 数据源与渲染分离:
dataList存纯数据,渲染时再生成JSX,这是React状态管理的标准做法,避免元素标识混乱。 - 函数式状态更新:新增和删除都用
setDataList(prev => ...),确保拿到最新的状态值,解决异步更新导致的错误。 - 直接传递ID:渲染时把当前项的
id直接传给删除函数,不用依赖dataset,避免目标元素匹配错误。 - 不可变更新:用
filter和扩展运算符生成新数组,不修改原状态,符合React状态不可变的要求。
内容的提问来源于stack exchange,提问作者guanmou wang
相关产品推荐
相关产品推荐

