Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to recursively render React components based on a deeply nested array?

Tags:

reactjs

with react js I'm trying to reach the continuing list as child in child child ... but here's the thing I'm stuck with, How can I list it? To give an example, I want the schema to be as follows

please keep in mind that I am new to react js when replying to or reading this thread. I may have a hard time Expressing Myself.

Menu 1 Menu Title
Menu 2 Menu Title
--Menu 2.1 Menu category-header
--Menu 2.2 Menu category-header
--Menu 2.3 Menu category-header
---Menu 2.3.1 Menu sub-category-header
---Menu 2.3.2 Menu sub-category-header
---Menu 2.3.3 Menu sub-category-header
----Menu 2.3.3.1 Menu sub-sub-category-header
----Menu 2.3.3.2 Menu sub-sub-category-header
const menuData = [
        {
            name: "Menu 1",
            url: "/"
        },
        {
            name: "Menu 2",
            children: [
                {
                    name: "Menu 2.1",
                    url: "/page/menu-2-1"
                },
                {
                    name: "Menu 2.2",
                    url: "/page/menu-4-2"
                },
                {
                    name: "Menu 2.3",
                    children: [
                        {
                            name: "Menu 2.3.1",
                            url: "/page/menu-2-3-1"
                        },
                        {
                            name: "Menu 2.3.2",
                            url: "/page/menu-2-3-2"
                        },
                        {
                            name: "Menu 2.3.3",
                            children: [
                                {
                                    name: "Menu 2.3.3.1",
                                    children: [
                                        {
                                            name: "Menu 2.3.3.1.1",
                                            url: "/page/menu-2-3-3-1-1"
                                        },
                                        {
                                            name: "Menu 2.3.3.1.2",
                                            url: "/page/menu-2-3-3-1-2"
                                        }
                                    ]
                                },
                                {
                                    name: "Menu 4.3.3.2",
                                    url: "/page/menu-4-3-3-2"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
const Menu = ({data}) => {
    const renderMenuItems = data => {
        return data.map(
            (item, index) =>
                (item?.children && item?.children.length) ?
                    (
                        console.log(item)
                    ) :
                    <li className="nav-item" key={index}>
                        <Link className="nav-link" to={item.url}>{item.name}</Link>
                    </li>

        )
    }
    return data && (
        <nav className="navbar navbar-expand-md navbar-main border-bottom">
            <div className="container">
                <div className="collapse navbar-collapse mobile-menu">
                    <ul className="nav navbar-nav">
                        {renderMenuItems(data)}
                    </ul>
                </div>
            </div>
        </nav>

    );
}
export default Menu;
<nav>
    <ul>
        <li>
            <a href="url">Menu 1</a>
        </li>
        <li>
            <a href="url" class="category-header">Woman</a>
            <div class="sub-nav">
                <div class="sub-nav-center">
                    <div class="sub-nav-outer">
                        <div class="normal-column">
                            <div class="category-box">
                                <a href="url" class="sub-category-header">Clothes</a>
                                <ul class="sub-item-list">
                                    <li>
                                        <a href="">T-shirt</a>
                                    </li>
                                    <li>
                                        <a href="">Shorts</a>
                                    </li>
                                    <li>
                                        <a href="">Shirt</a>
                                    </li>
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </li>
    </ul>
</nav>

enter image description here

enter image description here

like image 373
Selaminko Elam Avatar asked Apr 21 '26 16:04

Selaminko Elam


1 Answers

You have to recursively render each element until an element no longer has children.

I created a simple example using your data. Here, List maps and renders ListItem for each element of the array and ListItem again renders List if the element has children.

You can do something similar using your components.

const { useState, useEffect } = React;

const menuData = [
  {
    name: 'Menu 1',
    url: '/',
  },
  {
    name: 'Menu 2',
    children: [
      {
        name: 'Menu 2.1',
        url: '/page/menu-2-1',
      },
      {
        name: 'Menu 2.2',
        url: '/page/menu-4-2',
      },
      {
        name: 'Menu 2.3',
        children: [
          {
            name: 'Menu 2.3.1',
            url: '/page/menu-2-3-1',
          },
          {
            name: 'Menu 2.3.2',
            url: '/page/menu-2-3-2',
          },
          {
            name: 'Menu 2.3.3',
            children: [
              {
                name: 'Menu 2.3.3.1',
                children: [
                  {
                    name: 'Menu 2.3.3.1.1',
                    url: '/page/menu-2-3-3-1-1',
                  },
                  {
                    name: 'Menu 2.3.3.1.2',
                    url: '/page/menu-2-3-3-1-2',
                  },
                ],
              },
              {
                name: 'Menu 4.3.3.2',
                url: '/page/menu-4-3-3-2',
              },
            ],
          },
        ],
      },
    ],
  },
];

function ListItem({ listItem }) {
  const { name, url, children } = listItem;
  return (
    <li>
      <p>
        {name} - {url}
      </p>
      {Array.isArray(children) && <List list={children} />}
    </li>
  );
}

function List({ list }) {
  return (
    <ul>
      {list.map((listItem) => (
        <ListItem key={listItem.name} listItem={listItem} />
      ))}
    </ul>
  );
}
function App() {
  return <List list={menuData} />;
}

ReactDOM.render(<App />, document.querySelector('#root'));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
like image 169
Ramesh Reddy Avatar answered May 05 '26 23:05

Ramesh Reddy