React中如何遍历对象并按URL层级渲染对应组件
React 按URL从属关系渲染层级导航菜单
需求说明
给定如下扁平结构的路由数据:
export let data = { home: { title: "home", url: "/home" }, dashboard: { title: "dashboard", url: "/dashboard" }, pages: { title: "pages", url: "/pages" }, subpages: { title: "subpages", url: "/pages/subpages" }, login: { title: "login", url: "/pages/login" }, account: { title: "account", url: "/dashboard/account" } }
需要将其按URL从属关系(子路径归属于父路径节点下)渲染为层级结构,顶级节点用<h2>标签,子节点用<p>标签,最终效果如下:
Home dashboard account pages subpages login
实现步骤
1. 构建树形结构
首先需要把扁平的数据转换成带父子关系的树形结构,方便后续递归渲染:
// 将扁平对象转为数组 const items = Object.values(data); // 构建树形结构的函数 const buildTree = (items) => { // 创建URL到节点的映射,方便快速查找父节点 const urlMap = {}; items.forEach(item => { urlMap[item.url] = { ...item, children: [] }; }); const tree = []; items.forEach(item => { // 提取当前URL的父路径(去掉最后一段) const lastSlashIndex = item.url.lastIndexOf('/'); let parentUrl = item.url.substring(0, lastSlashIndex); // 处理根路径场景,比如"/home"截取后为空,统一设为"/" if (parentUrl === '') parentUrl = '/'; const parentNode = urlMap[parentUrl]; if (parentNode) { // 若存在父节点,将当前节点加入父节点的children数组 parentNode.children.push(urlMap[item.url]); } else { // 无父节点则作为顶级节点加入树形数组 tree.push(urlMap[item.url]); } }); return tree; }; // 生成树形结构数据 const menuTree = buildTree(items);
2. 递归渲染组件
编写React组件,递归渲染树形结构,顶级节点用<h2>,子节点用<p>并添加内边距体现层级:
// 单个菜单项组件 const MenuItem = ({ item }) => { // 首字母大写处理标题 const formattedTitle = item.title.charAt(0).toUpperCase() + item.title.slice(1); return ( <div> <h2>{formattedTitle}</h2> {/* 若有子节点,渲染子节点区域并添加左内边距 */} {item.children.length > 0 && ( <div style={{ paddingLeft: '20px' }}> {item.children.map(child => ( <p key={child.url}> {child.title.charAt(0).toUpperCase() + child.title.slice(1)} </p> ))} </div> )} </div> ); }; // 主应用组件 const App = () => { return ( <div className="menu-container"> {menuTree.map(item => ( <MenuItem key={item.url} item={item} /> ))} </div> ); }; export default App;
效果说明
运行上述代码后,会自动根据URL的从属关系生成层级导航:
- 顶级节点(home、dashboard、pages)用
<h2>渲染 - 子节点(account、subpages、login)用
<p>渲染并缩进20px,对应需求中的层级样式
内容的提问来源于stack exchange,提问作者Aditya B Vijay
相关产品推荐
相关产品推荐

