• React:通过嵌套对象循环


    问题描述:

    我正在从strapi 获取数据。我的导航对象的响应如下所示(简化):

    1. [
    2. {
    3. "id":1,
    4. "title":"Home",
    5. "order":1,
    6. "items":[
    7. {
    8. "id":2,
    9. "title":"3D Assets",
    10. "order":1,
    11. "items":[
    12. ]
    13. },
    14. {
    15. "id":4,
    16. "title":"3D Plants",
    17. "order":2,
    18. "items":[
    19. ]
    20. },
    21. {
    22. "id":3,
    23. "title":"Surfaces",
    24. "order":3,
    25. "items":[
    26. {
    27. "id":5,
    28. "title":"Asphalt",
    29. "order":1,
    30. "items":[
    31. ]
    32. }
    33. ]
    34. }
    35. ]
    36. },
    37. {
    38. "id":6,
    39. "title":"Collections",
    40. "order":2,
    41. "items":[
    42. ],
    43. "icon":""
    44. }
    45. ]

    实际上,我正在像这样循环浏览我的导航:

    1. {Object.entries(navigationItems).map(([key, value]) => {
    2. return(
    3. <div className="nav_item">
    4. <div className="nav_item_parent">{value.title}
    5. {Object.entries(value.items).map(([key, value]) => {
    6. return(
    7. <div className="nav_item_child">{value.title}
    8. {Object.entries(value.items).map(([key, value]) => {
    9. return(
    10. <div className="nav_item_child">{value.title}div>
    11. )
    12. })}
    13. div>
    14. )
    15. })}
    16. div>
    17. div>
    18. )
    19. })}

     

    如何在不为每个孩子重复代码的情况下创建导航?(因为对象可以嵌套很多次)

    解决思路一:

    我们可以使用深度优先遍历来帮助我们避免重复。如果您对深度优先遍历或递归不满意,我建议您先阅读以下代码段。

    1. function dfs(item, depth = 0) {
    2. if (!item || Object.keys(item).length === 0) return;
    3. console.log("\t".repeat(depth), item.title);
    4. for (const subItem of item.items) {
    5. dfs(subItem, depth + 1);
    6. }
    7. }
    8. // Consider payload to be the response that you get from the API.
    9. for (const item of payload) {
    10. dfs(item)
    11. }

    你就可以把它翻译成 React

    1. const Nav = ({ item, depth = 0 }) => {
    2. if (!item || Object.keys(item).length === 0) return;
    3. return (
    4. <>
    5. <p style={{ paddingLeft: `${depth * 64}px` }}>{item.title}p>
    6. {item.items.map((subItem, index) => (
    7. <Nav item={subItem} depth={depth + 1} />
    8. ))}
    9. );
    10. };
    11. export default function App() {
    12. return (
    13. <div className="App">
    14. {payload.map((item) => (
    15. <Nav item={item} />
    16. ))}
    17. div>
    18. );
    19. }

    解决思路二:

    只是一个简单的递归树遍历。像这样的组件:

    1. const NodePropTypes = PropTypes.objectWithShape({
    2. id: PropTypes.number,
    3. title: PropTypes.string,
    4. items: PropTypes.array,
    5. });
    6. const NavListPropTypes = {
    7. nodes: PropTypes.arrayOf( NodePropTypes ),
    8. };
    9. function NavList( props ) {
    10. const nodes = props?.nodes ?? [];
    11. if (nav.length) {
    12. return (
    13. <list>
    14. <ListItems nodes={nodes} />
    15. list>
    16. );
    17. }
    18. }
    19. NavList.propTypes = NavListPropTypes
    20. function ListItems( props ) {
    21. const nodes = props?.nodes ?? [];
    22. return (
    23. <>
    24. { nodes.map( node => <ListItem node={node} /> ) }
    25. );
    26. }
    27. ListItems.propTypes = NavListPropTypes;
    28. function ListItem( props ) {
    29. const node = props?.node ?? {};
    30. return (
    31. <li id={node.id} >
    32. <p> {node.title} p>
    33. <NavList nodes={node.items} />
    34. li>
    35. );
    36. }
    37. ListItem.propTypes = NodePropTypes;

    可以通过您的导航响应呈现:

    <NavList nodes={navigationResponse} />

    并且应该产生这样的结果:

    1. <li id="1" >
    2. <p> Home p>
    3. <list>
    4. <li id="2" >
    5. <p> 3D Assets p>
    6. li>
    7. <li id="4" >
    8. <p> 3d Plants p>
    9. li>
    10. <li id="3" >
    11. <p> Surfaces p>
    12. <list>
    13. <li id="5" >
    14. <p> Asphalt p>
    15. li>
    16. list>
    17. li>
    18. list>
    19. li>
    20. <li id="6" >
    21. <p> Collections p>
    22. li>

    解决思路三(这是解决小编问题的思路)

    以上仅为部分解决思路,添加下方公众号后回复001,即可查看全部内容。公众号有许多评分最高的编程书籍和其它实用工具,无套路,可放心使用

    如果您觉得有帮助,可以关注公众号——定期发布编程科技相关的资讯和资源

  • 相关阅读:
    气膜建筑的维护有哪些?
    Gephi弹出JVM Creation failed
    volatile 关键字有什么用?它的实现原理是什么?
    30天Python入门(第二十八天:深入了解Python API的使用)
    nodejs一对一npm多版本安装
    部署前后端为独立的 Docker 节点
    CF gym 103855 M 切比雪夫距离转换
    python资源库
    jupyter notebook安装中文及使用
    单元测试,集成测试,系统测试的区别是什么?
  • 原文地址:https://blog.csdn.net/qq_38334677/article/details/126119431