Simple Component for Multilevel Sidebar Menus in React

In this blog we will create a simple component for Multilevel sidebar menus in React. This will a reusable component that will receive data as props and render the sidebar navigation menus which supports N level of depth.

My Assumption is you are familiar with React Router Dom and its usage as I am using React Router Dom for Routing purpose in this application.

So let’s get Started :

Step 1: Create a Css File names MultilevelSideNav.css and put following code :

.multilevelSideNav {
  height: 100%;
  width: 0;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: #111;
  overflow-x: hidden;
  padding-top: 60px;
}

.multilevelSideNav a {
  padding: 8px 8px 8px 32px;
  text-decoration: none;
  font-size: 25px;
  color: #818181;
  display: block;
  transition: 0.3s;
}

.multilevelSideNav a:hover {
  color: #f1f1f1;
}

.multilevelSideNav .closebtn {
  position: absolute;
  top: 0;
  right: 25px;
  font-size: 36px;
  margin-left: 50px;
}

@media screen and (max-height: 450px) {
  .multilevelSideNav {padding-top: 15px;}
  .multilevelSideNav a {font-size: 18px;}
}

Step 2: Create a Side Nav Component named MultilevelSideNav.js with following code :

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import './MultilevelSideNav.css';
const MultilevelSideNav = ({ data, sideNavState, sideNavHandler }) => {

    const [currentMenus, setCurrentMenus] = useState(data);
    const [previousStack, setPreviousStack] = useState([]);
    const renderMenuItems = data => {

        return data.map((item, index) =>
            (item?.children && item?.children.length) ? (
                <Link key={index}
                    onClick={e => {
                        previousStack.push(data);
                        setPreviousStack(previousStack);
                        setCurrentMenus(item.children)
                    }}
                    to={"#"}>{item.name} &gt; </Link>

            ) : <Link key={index} to={item.url}>{item.name}</Link>
        )
    }
    return data && (
        <div style={{ width: (sideNavState) ? '250px' : '0' }} className="multilevelSideNav">
            <Link to={"#"} className="closebtn" onClick={e => sideNavHandler(false)}>&times;</Link>
            {(previousStack.length) ?
                <Link to={"#"} onClick={e => {
                    const prevState = previousStack.pop();
                    setPreviousStack(previousStack);
                    setCurrentMenus(prevState);

                }}>&lt; Back</Link>
                : null
            }
            {
                renderMenuItems(currentMenus)
            }
        </div>
    );
}
export default MultilevelSideNav;

Now we will create 2 components for url handleing 1 for Showing Home page and another for showing
Page relevant information.

Step 3: Create a simple Home Component Home.js Like this:

const Home = () => {
return (
    <h1>This is my Home Page</h1>
  );
}
export default Home;

Step 4: Create a Page Component Page.js that will show a menu Title by its Slug :

import React from 'react'
import { useParams } from 'react-router-dom';
const Page = () => {
    const { slug } = useParams();
    return (
        <h1>This is Page for {slug.replace("menu-","Menu ").replace(/-/g,".")}</h1>
    );
}
export default Page;

Now we are ready to Call our MultilevelSideNav Component that we have created in Step 2

Step 5: lets do the changes in App.js to call MultilevelSideNav Component :

Constructing the menu data, you may grab this data from your api as well

const menuData = [
    {
      name: "Home",
      url: "/"
    },
    {
      name: "Menu 1",
      children: [
        {
          name: "Menu 1.1",
          url: "/page/menu-1-1"
        }
      ]
    },
    {
      name: "Menu 2",
      url: "/page/menu-2"
    },
    {
      name: "Menu 3",
      children: [
        {
          name: "Menu 3.1",
          url: "/page/menu-3-1"
        },
        {
          name: "Menu 3.2",
          url: "/page/menu-3-2"
        },
        {
          name: "Menu 3.3",
          children: [
            {
              name: "Menu 3.3.1",
              url: "/page/menu-3-3-1"
            },
          ]
        }
      ]
    },
    {
      name: "Menu 4",
      children: [
        {
          name: "Menu 4.1",
          url: "/page/menu-4-1"
        },
        {
          name: "Menu 4.2",
          url: "/page/menu-4-2"
        },
        {
          name: "Menu 4.3",
          children: [
            {
              name: "Menu 4.3.1",
              url: "/page/menu-4-3-1"
            },
            {
              name: "Menu 4.3.2",
              url: "/page/menu-4-3-2"
            },
            {
              name: "Menu 4.3.3",
              children: [
                {
                  name: "Menu 4.3.3.1",
                  children: [
                    {
                      name: "Menu 4.3.3.1.1",
                      url: "/page/menu-4-3-3-1-1"
                    }
                  ]
                },
                {
                  name: "Menu 4.3.3.2",
                  url: "/page/menu-4-3-3-2"
                }
              ]
            }
          ]
        }
      ]
    }
  ]

and Finally this will be our JSX return in App.js

return (
    <div className="App">
      <Router>
        <MultilevelSideNav sideNavState={sideNavState} sideNavHandler={setSideNavState} data={menuData} />
        <div style={{marginLeft:(sideNavState)?'250px':'0'}}>
          <h2><span style={{fontSize:'30px',cursor:'pointer'}} onClick={e=>setSideNavState(true)}>&#9776; Open SideNav</span></h2>      
          <Switch> 
          <Route path="/page/:slug">
             <Page />
          </Route>
          <Route path="/">
             <Home/>
          </Route>
        </Switch>
        </div>        
      </Router>
    </div>

Note : As I mentioned earlier as well I am using React Router Dom to handle page click and showing relevant page information once landing to any page

And Finally lets see how our App will look this :

Thats it we have created our multilevel sidebar menus in react js. if you face any issue in creating this component on your system please let me know in comments section. Also Suggestions or Feedbacks for improvement are welcome.

You may Download the complete source code by clicking this link

Simple Component for Multilevel Navigation Menus in React

In this Blog we will create a simple application for Multilevel Navigation Menus in React Js which accepts data through props and display Nth Level Navigation Menus.
Assuming you have already using react-router-dom as we are using that to handle the Routing and Navigation Links in this demo.

So let’s get started :

Step 1: Create a MultilevelMenu.css file and put following css code :

.multilevelMenu ul {
  list-style: none;
  padding: 0;
  margin: 0;
  background: #2c3e50;
}

.multilevelMenu ul li {
  display: block;
  position: relative;
  float: left;
  background: #2c3e50;
}
.multilevelMenu li ul {
  display: none;
}

.multilevelMenu ul li a {
  display: block;
  padding: 1em;
  text-decoration: none;
  white-space: nowrap;
  color: #fff;
}

.multilevelMenu ul li a:hover {
  background: #151e27;
}
.multilevelMenu li:hover > ul {
  display: block;
  position: absolute;
}

.multilevelMenu li:hover li {
  float: none;
}
.multilevelMenu ul ul ul {
  left: 100%;
  top: 0;
}
.multilevelMenu ul:before,
.multilevelMenu ul:after {
  content: " "; /* 1 */
  display: table; /* 2 */
}

.multilevelMenu ul:after { clear: both; }

.multilevelMenu li:hover a {
  background: #2c3e50;
}

.multilevelMenu li:hover li a:hover {
  background: #151e27;
}

.multilevelMenu .main-navigation li ul li {
  border-top: 0;
}

Step 2: Create a Component Named MultilevelMenu.js with following code :


import React from 'react';
import { Link } from 'react-router-dom';
import './MultilevelMenu.css';
const MultilevelMenu = ({ data }) => {
    const renderMenuItems = data => {
        return data.map((item, index) =>
            (item?.children && item?.children.length) ? (<li key={index}><Link to={"#"}>{item.name}</Link><ul>
                {renderMenuItems(item.children)}
            </ul></li>
            ) : <li key={index}><Link to={item.url}>{item.name}</Link></li>
        )
    }
    return data && (
        <div className="multilevelMenu">
            <ul className="main-navigation">
                {renderMenuItems(data)}
            </ul>
        </div>
    );
}
export default MultilevelMenu;

Now your Component is ready but if we click on any menu/url that there should be 2 component, 1 for Home page and 1 for other pages as per url slug passed.

Step 3: Create a simple Home Component Home.js Like this:

const Home = () => {
return (
    <h1>This is my Home Page</h1>
  );
}
export default Home;

Step 4: Create a Page Component Page.js that will show a menu Title by its Slug using following code :

import React from 'react'
import { useParams } from 'react-router-dom';
const Page = () => {
    const { slug } = useParams();
    return (
        <h1>This is Page for {slug.replace("menu-","Menu ").replace(/-/g,".")}</h1>
    );
}
export default Page;

Now we are ready to Call our Multilevel menu Component

Step 5: In this Step we’ll do the changes in App.js File

First add the dummy menus data, you may get similar structure data from api as well if needed.

const menuData = [
    {
      name: "Home",
      url: "/"
    },
    {
      name: "Menu 1",
      children: [
        {
          name: "Menu 1.1",
          url: "/page/menu-1-1"
        }
      ]
    },
    {
      name: "Menu 2",
      url: "/page/menu-2"
    },
    {
      name: "Menu 3",
      children: [
        {
          name: "Menu 3.1",
          url: "/page/menu-3-1"
        },
        {
          name: "Menu 3.2",
          url: "/page/menu-3-2"
        },
        {
          name: "Menu 3.3",
          children: [
            {
              name: "Menu 3.3.1",
              url: "/page/menu-3-3-1"
            },
          ]
        }
      ]
    },
    {
      name: "Menu 4",
      children: [
        {
          name: "Menu 4.1",
          url: "/page/menu-4-1"
        },
        {
          name: "Menu 4.2",
          url: "/page/menu-4-2"
        },
        {
          name: "Menu 4.3",
          children: [
            {
              name: "Menu 4.3.1",
              url: "/page/menu-4-3-1"
            },
            {
              name: "Menu 4.3.2",
              url: "/page/menu-4-3-2"
            },
            {
              name: "Menu 4.3.3",
              children: [
                {
                  name: "Menu 4.3.3.1",
                  children: [
                    {
                      name: "Menu 4.3.3.1.1",
                      url: "/page/menu-4-3-3-1-1"
                    }
                  ]
                },
                {
                  name: "Menu 4.3.3.2",
                  url: "/page/menu-4-3-3-2"
                }
              ]
            }
          ]
        }
      ]
    }
  ]

Now we have the data ready, Next we need to do modify our JSX return Statement like this:

<div className="App">
      <Router>
        <MultilevelMenu data={menuData} />
        <Switch> 
          <Route path="/page/:slug">
             <Page />
          </Route>
          <Route path="/">
             <Home/>
          </Route>
        </Switch>
      </Router>
    </div>

Note : As we have mentioned we are using React Router Dom to handle click on various menus, Home page will show the Home component and All other multi level menus will land on Page component so that all pages can land and show page menu somewhere and we can see the menus in Action

Lets See How finally our App looks Like :

Hope This is Something Helpful to you, In case any suggestions or difficulties please let me know in comments.

TO DOWNLOAD THE WHOLE CODE CLICK ON THIS LINK