问题描述:
我正在从strapi 获取数据。我的导航对象的响应如下所示(简化):
[
{
"id":1,
"title":"Home",
"order":1,
"items":[
{
"id":2,
"title":"3D Assets",
"order":1,
"items":[
]
},
{
"id":4,
"title":"3D Plants",
"order":2,
"items":[
]
},
{
"id":3,
"title":"Surfaces",
"order":3,
"items":[
{
"id":5,
"title":"Asphalt",
"order":1,
"items":[
]
}
]
}
]
},
{
"id":6,
"title":"Collections",
"order":2,
"items":[
],
"icon":""
}
]
实际上,我正在像这样循环浏览我的导航:
{Object.entries(navigationItems).map(([key, value]) => {
return(
<div className="nav_item">
<div className="nav_item_parent">{value.title}
{Object.entries(value.items).map(([key, value]) => {
return(
<div className="nav_item_child">{value.title}
{Object.entries(value.items).map(([key, value]) => {
return(
<div className="nav_item_child">{value.title}</div>
)
})}
</div>
)
})}
</div>
</div>
)
})}
如何在不为每个孩子重复代码的情况下创建导航?(因为对象可以嵌套很多次)
解决思路一:
我们可以使用深度优先遍历来帮助我们避免重复。如果您对深度优先遍历或递归不满意,我建议您先阅读以下代码段。
function dfs(item, depth = 0) {
if (!item || Object.keys(item).length === 0) return;
console.log("\t".repeat(depth), item.title);
for (const subItem of item.items) {
dfs(subItem, depth + 1);
}
}
// Consider payload to be the response that you get from the API.
for (const item of payload) {
dfs(item)
}
你就可以把它翻译成 React
const Nav = ({ item, depth = 0 }) => {
if (!item || Object.keys(item).length === 0) return;
return (
<>
<p style={{ paddingLeft: `${depth * 64}px` }}>{item.title}</p>
{item.items.map((subItem, index) => (
<Nav item={subItem} depth={depth + 1} />
))}
</>
);
};
export default function App() {
return (
<div className="App">
{payload.map((item) => (
<Nav item={item} />
))}
</div>
);
}
解决思路二:
只是一个简单的递归树遍历。像这样的组件:
const NodePropTypes = PropTypes.objectWithShape({
id: PropTypes.number,
title: PropTypes.string,
items: PropTypes.array,
});
const NavListPropTypes = {
nodes: PropTypes.arrayOf( NodePropTypes ),
};
function NavList( props ) {
const nodes = props?.nodes ?? [];
if (nav.length) {
return (
<list>
<ListItems nodes={nodes} />
</list>
);
}
}
NavList.propTypes = NavListPropTypes
function ListItems( props ) {
const nodes = props?.nodes ?? [];
return (
<>
{ nodes.map( node => <ListItem node={node} /> ) }
</>
);
}
ListItems.propTypes = NavListPropTypes;
function ListItem( props ) {
const node = props?.node ?? {};
return (
<li id={node.id} >
<p> {node.title} </p>
<NavList nodes={node.items} />
</li>
);
}
ListItem.propTypes = NodePropTypes;
可以通过您的导航响应呈现:
<NavList nodes={navigationResponse} />
并且应该产生这样的结果:
<list>
<li id="1" >
<p> Home </p>
<list>
<li id="2" >
<p> 3D Assets </p>
</li>
<li id="4" >
<p> 3d Plants </p>
</li>
<li id="3" >
<p> Surfaces </p>
<list>
<li id="5" >
<p> Asphalt </p>
</li>
</list>
</li>
</list>
</li>
<li id="6" >
<p> Collections </p>
</li>
</list>
解决思路三(这是解决小编问题的思路):
以上仅为部分解决思路,添加下方公众号后回复001,即可查看全部内容。公众号有许多评分最高的编程书籍和其它实用工具,无套路,可放心使用
如果您觉得有帮助,可以关注公众号——定期发布编程科技相关的资讯和资源