React递归删除嵌套对象数组元素问题排查
嵌套数组元素删除失效的问题排查与修复
原代码的核心错误
- 逻辑倒置:原代码仅在当前元素ID匹配目标ID时才尝试递归处理子元素,但实际上应该在当前元素ID不匹配时,去递归清理它的子元素——否则嵌套层级的目标元素永远不会被检测到。
- 未更新嵌套结构:递归调用时,即使处理了子元素数组,也没有将处理后的子数组赋值回当前元素,导致修改无法同步到最终结果。
- 不必要的多次状态更新:原函数在递归过程中每次都调用
setState,会触发多次状态更新,且最终结果可能被覆盖。
修正后的代码
import React, { useState, useEffect } from 'react'; let array = [ { id: 1, title: 'text 1', children: [ { id: 5, title: 'text 5', children: [], }, { id: 6, title: 'text 6', children: [], }, ], }, { id: 2, title: 'text 2', children: [], }, { id: 3, title: 'text 3', children: [ { id: 7, title: 'text 7', children: [], }, ], }, { id: 4, title: 'text 4', children: [], }, ]; export const Component = () => { const [state, setState] = useState(array); // 纯函数:递归处理数组,返回删除指定ID后的新数组 const deleteItemById = (arr, targetId) => { return arr .filter(item => item.id !== targetId) .map(item => ({ ...item, // 递归处理子元素,更新当前元素的children children: deleteItemById(item.children, targetId) })); }; const onDelete = (id) => { const newState = deleteItemById(state, id); setState(newState); }; useEffect(() => { onDelete(5); }, []); // 递归渲染数组,验证删除结果 const renderItems = (items) => ( <ul> {items.map(item => ( <li key={item.id}> {item.title} {item.children.length > 0 && renderItems(item.children)} </li> ))} </ul> ); return <div>{renderItems(state)}</div>; };
关键修正说明
- 拆分出纯函数
deleteItemById:负责递归遍历整个数组,返回全新的结构,符合React状态不可变的更新要求,避免直接修改原数据。 - 先过滤再递归:先移除当前层级中ID匹配的元素,再对剩下的元素递归处理其子数组,确保所有嵌套层级的目标元素都被清理。
- 单次状态更新:完成整个数组的处理后,再调用一次
setState,避免多次更新导致的混乱。 - 添加渲染逻辑:通过递归渲染可以直观验证嵌套元素是否被成功删除。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

