JS:如何删除对象数组中的子对象并保留父-子层级结构?
解决社交媒体评论层级结构下的子评论删除问题
问题分析
你当前的删除函数仅能处理父评论删除,处理子评论时要么无法定位删除目标,要么会把子评论从父评论的replies数组中移出,直接放到顶级评论数组里,彻底破坏原有的parent>child层级结构。第二个改进函数还存在循环越界问题:循环结束后i等于comments.length,访问comments[i]会得到undefined,直接触发报错。
正确实现方案
以下是符合需求的删除函数,既能删除指定ID的父/子评论,又能完整保留原有的层级结构:
function handleClick(e) { const targetId = Number(e.target.id); setLoading(true); // 生成更新后的评论数组,严格保留层级关系 const updatedComments = comments .map(comment => { // 若当前父评论是删除目标,返回null后续过滤移除 if (comment.id === targetId) { return null; } // 浅拷贝父评论,同时过滤其子评论列表中的目标项 return { ...comment, replies: comment.replies.filter(reply => reply.id !== targetId) }; }) .filter(Boolean); // 移除被标记为删除的父评论 // 更新评论状态 setComments(updatedComments); setTimeout(() => { setLoading(false); }, 1000); }
代码逻辑说明
- 目标ID转换:将点击事件触发的ID转为数字类型,确保与评论ID的类型匹配。
- 父评论遍历处理:
- 用
map遍历每个父评论,若父评论ID等于目标ID,返回null,后续通过filter(Boolean)将其从数组中移除(处理删除父评论的场景)。 - 若父评论不是目标,则浅拷贝该父评论,并对其
replies数组执行filter操作,移除ID匹配的子评论,保证子评论始终处于原父评论的层级下。
- 用
- 状态更新:将处理后的新数组赋值给
comments状态,严格遵循React状态不可变的原则。
额外优化建议
为避免事件冒泡导致的ID获取错误,建议将按钮的ID存储在data-id属性中,通过e.currentTarget获取:
// 按钮元素写法 <button data-id={comment.id} onClick={handleClick}>删除</button> // 函数中获取ID的方式 const targetId = Number(e.currentTarget.dataset.id);
内容的提问来源于stack exchange,提问作者Ninety9Balloons
相关产品推荐
相关产品推荐

