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

React中如何实现递归方法处理树形数据?

解决React中树形结构的递归数据处理问题

我明白你现在的困扰——要递归遍历嵌套的文件夹结构,收集选中文件和展开文件夹的key对吧?你的现有方法只能处理一层子节点,没法深入多层嵌套结构,我来帮你修正这个问题。

首先明确核心需求:

  • 遍历整个树形结构,不管嵌套多少层级
  • 收集所有checked: true节点(主要是文件)的key到checkedKeys数组
  • 收集所有expanded: true文件夹的key到expandedKeys数组

问题分析

你之前尝试的递归写法有个关键错误:data.children是一个数组,你直接把数组传给checkItemCheckeds方法,导致方法里的data变成了数组,自然没法访问data.checked这类节点属性。正确的做法是遍历每个子节点,逐个递归调用方法。

正确的递归实现

1. 收集选中节点的递归方法

这个方法会遍历每个节点,若为选中的文件则加入数组,同时递归处理所有子节点:

checkItemCheckeds = (data) => {
  // 处理当前节点:如果是叶子节点(文件)且选中,加入checkedKeys
  if (data.isLeaf && data.checked) {
    this.checkedKeys.unshift(data.key);
  }

  // 如果有子节点,递归遍历每个子项
  if (data.children && data.children.length > 0) {
    data.children.forEach(item => this.checkItemCheckeds(item));
  }
}

2. 收集展开文件夹的递归方法

同样的思路,遍历每个文件夹,若处于展开状态则加入数组,再递归处理子文件夹:

checkExpandedFolders = (data) => {
  // 处理当前节点:如果是文件夹且展开,加入expandedKeys
  if (data.type === 'folder' && data.expanded) {
    this.expandedKeys.unshift(data.key);
  }

  // 递归处理所有子节点
  if (data.children && data.children.length > 0) {
    data.children.forEach(item => this.checkExpandedFolders(item));
  }
}

整合到现有代码

调整loadJSON和addItem方法,让递归逻辑更清晰:

loadJSON = (tree) => {
  this.treeData = [];
  this.checkedKeys = [];
  this.expandedKeys = [];

  // 遍历每个根节点
  tree.forEach(item => {
    this.addItem(item);
    // 对每个根节点启动递归检查
    this.checkItemCheckeds(item);
    this.checkExpandedFolders(item);
  });

  // 最后统一更新状态
  this.setState({
    treeData: this.treeData,
    checkedKeys: this.checkedKeys,
    expandedKeys: this.expandedKeys
  });
}

addItem = (data) => {
  const dataItem = {
    name: data.name,
    key: data.key,
    isLeaf: data.isLeaf,
    type: data.type,
    checked: data.checked,
    expanded: data.expanded,
    // 复制子节点(如果有的话)
    children: data.children ? [...data.children] : undefined
  };
  this.treeData.unshift(dataItem);
}

对你最终代码的优化建议

你后来找到的代码有个小瑕疵:只有当子节点没选中时才会递归,这会导致如果一个文件夹的子节点是选中的文件,就不会递归检查这个节点的子项(虽然文件是叶子节点没有子项,但如果是选中的文件夹,就会漏掉它下面的选中文件)。所以最好不管子节点是否选中,都递归遍历,确保所有层级的节点都被检查到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:27:07