React应用未知层级嵌套导航数据结构设计与遍历实现
React 无限层级导航数据遍历方案
问题说明
为React应用开发导航功能时,开发者对导航数据源拥有完全控制权,但导航子节点的嵌套层级未知,需要实现可覆盖任意嵌套深度的单函数遍历逻辑,也接受通过调整数据结构简化实现的方案。
当前已完成第一层导航的转换逻辑,但无法处理多层嵌套的子节点,原始实现代码如下:
const data = { "nav": { "Nav Menu Title 1" : { "children": [ { "name": "Sub Menu Title 1", "children" : [ { "name": "Sub Sub Menu Title 1", "children" : [ { "name": "Sub Sub Menu Option 1" } ] }, { "name" : "Sub Menu Option 1" } ] }, { "name": "Option 1" }, { "name": "Option 2" }, { "name": "Option 3" }, { "name": "Option 4" }, { "name": "Option 5" } ] } } } for (let items in data.nav) { let newNavItem = { id: 'apps.' + items, title: items, type: 'item', icon: 'heroicons-outline:shopping-cart' } if (data.nav[items].children.length > 0) { newNavItem.type = "collapse"; newNavItem.children = []; // 此处无法实现多层子节点的遍历逻辑 } }
实现方案
方案1:递归遍历(无需修改现有数据结构)
核心逻辑是封装通用的单节点转换函数,只要节点存在非空子节点数组,就递归调用该函数处理所有子节点,自动适配任意嵌套深度。
完整实现代码:
/** * 转换单个导航节点 * @param {string} nodeName 当前节点名称 * @param {object} rawNode 原始节点数据 * @param {string} idPrefix 生成id的前缀 * @returns 转换后的导航节点 */ function transformNavNode(nodeName, rawNode, idPrefix) { // 构造基础节点结构 const navItem = { id: `${idPrefix}${nodeName}`, title: nodeName, type: 'item', icon: 'heroicons-outline:shopping-cart' } // 存在子节点时递归处理 if (rawNode.children?.length) { navItem.type = 'collapse' navItem.children = rawNode.children.map(childItem => transformNavNode(childItem.name, childItem, `${navItem.id}.`) ) } return navItem } // 遍历顶级导航节点,生成完整导航树 const finalNav = [] for (const topNavName in data.nav) { finalNav.push( transformNavNode(topNavName, data.nav[topNavName], 'apps.') ) }
运行后finalNav就是符合要求的完整导航结构,不管子节点嵌套多少层都可以正确转换。
方案2:统一数据结构(可选优化)
如果可以调整数据源格式,建议把所有层级的导航节点统一为{name: '菜单名', children: []}的结构,顶级节点也存为数组,不需要用对象key存储菜单名称,处理逻辑会更简洁,不需要单独区分顶级节点和子节点的处理逻辑。
调整后的数据结构示例:
const data = { nav: [ { name: "Nav Menu Title 1", children: [ // 后续子节点结构和原有子节点保持一致即可 ] } ] }
统一结构后,只需要直接遍历data.nav数组,调用上面的transformNavNode函数即可,不需要额外写for...in循环处理顶级对象。
内容的提问来源于stack exchange,提问作者Ancesteral
相关产品推荐
相关产品推荐

