You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript实现递归修改树形结构节点isDisabled布尔值的问题

现有代码的核心问题

  • 问题1:find 函数中遍历子节点调用 map 生成的更新后子节点数组没有被回写到当前节点的 children 属性上,子节点的修改全部丢失,最终返回的是未更新子节点的旧结构。
  • 问题2:find 没有遵循不可变更新逻辑,当前节点未匹配到目标ID时直接返回原对象,没有基于更新后的子节点生成新的节点对象,导致上层节点无法感知子树的修改。

修复后的代码

type DataType = {
  id: string;
  access: 'view' | 'none';
  isDisabled: boolean;
  children: DataType[];
};

export const find = (data: DataType, selectedId: string, access: 'view' | 'none'): DataType => {
  if (!selectedId || !access) {
    return data;
  }

  // 当前节点命中目标ID,直接调用修改方法
  if (data.id === selectedId) {
    return changeAccess(data, selectedId, access);
  }

  // 遍历子节点更新,返回新的节点对象,避免修改原数据
  return {
    ...data,
    children: data.children.map(child => find(child, selectedId, access))
  };
};

// changeAccess原有逻辑符合需求,无需调整
export const changeAccess = (data: DataType, selectedId: string, access: 'view' | 'none'): DataType => ({
  ...data,
  access: access,
  isDisabled: data.id !== selectedId && access !== 'view' ? true : false,
  children: data.children?.map((child) =>
    changeAccess(child, selectedId, access)
  ),
});

效果验证

调用 const result = find(Data, '2', 'none'); 即可匹配预期输出:

  • 节点2的access变为none,isDisabled保持false
  • 节点2的所有子节点(id3、id4)access变为none,isDisabled变为true
  • 其余节点属性保持不变

内容的提问来源于stack exchange,提问作者webber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:12:03