问题描述:
我正在从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} />
并且应该产生这样的结果:
- <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>
解决思路三(这是解决小编问题的思路):
以上仅为部分解决思路,添加下方公众号后回复001,即可查看全部内容。公众号有许多评分最高的编程书籍和其它实用工具,无套路,可放心使用
如果您觉得有帮助,可以关注公众号——定期发布编程科技相关的资讯和资源