遍历嵌套对象数组更新指定ID状态失效问题排查
嵌套对象数组修改指定节点状态后返回原数组的问题
需求与问题
- 需求:遍历对象数组,在深层嵌套对象中查找指定ID,找到后将该节点的
status修改为Activated,并返回完整的更新后数组。 - 问题:当前代码能进入匹配ID的
if语句,但最终返回的仍是原输入数组,未得到更新结果。
原代码
TypeScript版本
export function findChild(array: any, id: string): array { return array.map((node) => { if (node.id === id) { return { ...node, status: 'Activated' }; } else { if (node.children?.length) { findChild(node.children, id); } } return node; }); }
JavaScript版本及输入示例
function findChild(array, id) { return array.map((node) => { if (node.id === id) { return { ...node, status: 'Activated' }; } else { if (node.children?.length) { findChild(node.children, id); } } return node; }); } // 输入示例 let input = [{ id: '1', amt: '30', status: 'Active', children: [{ id: 'SG2', amt: '305', status: 'Active', }, { id: '5', amt: '30', status: 'Active', children: [], }, ], }, { id: '6', amt: '307', status: 'Active', children: [], }, { id: '7', amt: '40', status: 'Inactive', children: [{ id: '7', amt: '40', status: 'Inactive', children: [] }], }, { id: '8', amt: '100', status: 'Dead', children: [], }, ]; // 原调用方式 findChild(input,7) console.log(input)
问题根源
- 递归结果未复用:递归调用
findChild(node.children, id)时,只是执行了函数但没有将返回的更新后子数组赋值回当前节点,原节点的children还是旧的引用,导致上层节点无法感知子树的修改。 - 未接收函数返回值:原代码直接打印原
input数组,但该函数是纯函数(不会修改原数组,而是返回新数组),必须接收返回值才能拿到更新后的结果。
修复后的代码
TypeScript版本
export function findChild(array: any[], id: string): any[] { return array.map((node) => { // 匹配到目标ID,返回修改status后的新节点 if (node.id === id) { return { ...node, status: 'Activated' }; } // 递归处理子节点,拿到更新后的子数组 const updatedChildren = node.children?.length ? findChild(node.children, id) : node.children; // 返回包含更新后子节点的新节点 return { ...node, children: updatedChildren }; }); }
JavaScript版本
function findChild(array, id) { return array.map((node) => { if (node.id === id) { return { ...node, status: 'Activated' }; } const updatedChildren = node.children?.length ? findChild(node.children, id) : node.children; return { ...node, children: updatedChildren }; }); }
正确使用方式
// 接收函数返回的更新后数组 const updatedInput = findChild(input, '7'); // 打印更新后的结果 console.log(updatedInput);
修复说明
- 递归处理子节点时,将返回的更新后子数组赋值给
updatedChildren,并通过对象展开运算符创建新节点,替换原节点的children,确保整个树的修改能向上传递。 - 函数保持纯函数特性,不修改原数组,所有修改都基于新创建的对象,避免副作用。
内容的提问来源于stack exchange,提问作者Sarah Mandana
相关产品推荐
相关产品推荐

