Multilevel dropdown menu creating in ReactJS
ReactJS
Multilevel
dropdown
menu
NextJS
- By Sudarshan Vishwakarma
- Mar 30th, 2022
- 0 comments
- 12
Multilevel dropdown menus are a staple of web design. With the ability to provide multiple options to select from, they make navigation bars dynamic and organized.
For any developer working in React or any React-based project like Gatsby or Next.js, this tutorial covers the step-by-step process of how to implement the dropdown feature in a React project. At the end of this guide, we will have the menu below:

To follow this tutorial, ensure you have a basic understanding of React and confirm you have Node.js installed on your computer. Then, we can get started.
Setting up the React project
Let’s start by creating a new React project called multilevel-dropdown-menu by running the following command:
npx create-react-app react-multilevel-dropdown-menu
Once the project generates, navigate inside the project folder using cd multilevel-dropdown-menu or simply open the project with a code editor.
Then, run the npm start built-in command to start the project in development mode. The app should launch in the browser at http://localhost:3000.
Creating the project files
Head over to the src folder and delete all the files except the index.js. Next, create a folder called components inside the src and add the following component files: Dropdown.js, MenuItems.js and Navbar.js.
In the App.js file, add the following starting code:
import Navbar from "./components/Navbar";
const App = () => {
return ( <
header >
<
div className = "nav-area" >
<
a href = "/#"
className = "logo" >
CodeSolution <
/a> <
Navbar / >
<
/div> < /
header >
);
};
export default App;
Rendering top-level menu items
Let’s start building by rendering the top menu items. To do this, we must get the menu data by creating a menuItems.js file in the src folder and add the following:
export const menuItems = [{
title: "Home",
},
{
title: "Services",
submenu: [{
title: "web design",
},
{
title: "web development",
submenu: [{
title: "Frontend",
},
{
title: "Backend",
submenu: [{
title: "NodeJS",
},
{
title: "PHP",
},
],
},
],
},
{
title: "SEO",
},
],
},
{
title: "About",
submenu: [{
title: "Who we are",
},
{
title: "Our values",
},
],
},
];
Moving on, notice we imported the Navbar component. So, head over to the components/Navbar.js and add the following code:
import {
menuItems
} from "../menuItems";
import MenuItems from "./MenuItems";
const Navbar = () => {
return ( <
nav >
<
ul className = "menus" > {
menuItems.map((menu, index) => {
const depthLevel = 0;
return <MenuItems items = {
menu
}
key = {
index
}
depthLevel = {
depthLevel
}
/>;
})
} <
/ul> <
/nav>
);
};
export default Navbar;
Open the components/MenuItems.js file and add the following code:
import {
useState,
useEffect,
useRef
} from "react";
import Dropdown from "./Dropdown";
const MenuItems = ({
items,
depthLevel
}) => {
const [dropdown, setDropdown] = useState(false);
let ref = useRef();
useEffect(() => {
const handler = (event) => {
if (dropdown && ref.current && !ref.current.contains(event.target)) {
setDropdown(false);
}
};
document.addEventListener("mousedown", handler);
document.addEventListener("touchstart", handler);
return () => {
// Cleanup the event listener
document.removeEventListener("mousedown", handler);
document.removeEventListener("touchstart", handler);
};
}, [dropdown]);
const onMouseEnter = () => {
window.innerWidth > 960 && setDropdown(true);
};
const onMouseLeave = () => {
window.innerWidth > 960 && setDropdown(false);
};
return ( <
li className = "menu-items"
ref = {
ref
}
onMouseEnter = {
onMouseEnter
}
onMouseLeave = {
onMouseLeave
} >
{
items.submenu ? ( <
>
<
button type = "button"
aria - haspopup = "menu"
aria - expanded = {
dropdown ? "true" : "false"
}
onClick = {
() => setDropdown((prev) => !prev)
} >
{
items.title
} {
" "
} {
depthLevel > 0 ? < span > & raquo; < /span> : <span className="arrow" / >
} <
/button> <
Dropdown depthLevel = {
depthLevel
}
submenus = {
items.submenu
}
dropdown = {
dropdown
}
/> <
/>
) : ( <
a href = "/#" > {
items.title
} < /a>
)
} <
/li>
);
};
export default MenuItems;
Let’s now open the components/Dropdown.js file and access the prop so we can render the submenu like so:
import MenuItems from "./MenuItems";
const Dropdown = ({
submenus,
dropdown,
depthLevel
}) => {
depthLevel = depthLevel + 1;
const dropdownClass = depthLevel > 1 ? "dropdown-submenu" : "";
return ( <
ul className = {
`dropdown ${dropdownClass} ${dropdown ? "show" : ""}`
} > {
submenus.map((submenu, index) => ( <
MenuItems items = {
submenu
}
key = {
index
}
depthLevel = {
depthLevel
}
/>
))
} <
/ul>
);
};
export default Dropdown;
Open the src/app.css file and temporarily comment-out the display: none; part of the CSS:
*{
margin: 0;
padding: 0;
box - sizing: border - box;
}
body {
font - family: sans - serif;
}
header {
height: 58 px;
box - shadow: 0 1 px 3 px 0 rgba(0, 0, 0, 0.07),
0 1 px 2 px 0 rgba(0, 0, 0, 0.05);
color: #212529;
}
.nav-area {
display: flex;
align-items: center;
max-width: 100%;
margin: 0 auto;
padding: 0 20px;
height: 58px;
}
.logo {
text-decoration: none;
font-size: 25px;
color: inherit;
margin-right: 20px;
}
.menus {
display: flex;
list-style: none;
}
.menu-items {
position: relative;
font-size: 14px;
}
.menu-items a {
display: block;
font-size: inherit;
color: inherit;
text-decoration: none;
}
.menu-items button {
color: inherit;
font-size: inherit;
border: none;
background-color: transparent;
cursor: pointer;
width: 100%;
}
.menu-items a,
.menu-items button {
text-align: left;
padding: 0.7rem 1rem;
}
.menu-items a:hover,
.menu-items button:hover {
background-color: # f2f2f2;
}
.arrow::after {
content: "";
display: inline - block;
margin - left: 0.28 em;
vertical - align: 0.09 em;
border - top: 0.42 em solid;
border - right: 0.32 em solid transparent;
border - left: 0.32 em solid transparent;
}
.dropdown {
position: absolute;
right: 0;
left: auto;
box - shadow: 0 10 px 15 px - 3 px rgba(46, 41, 51, 0.08),
0 4 px 6 px - 2 px rgba(71, 63, 79, 0.16);
font - size: 0.875 rem;
z - index: 9999;
min - width: 10 rem;
padding: 0.5 rem 0;
list - style: none;
background - color: #fff;
border - radius: 0.5 rem;
display: none;
}
.dropdown.show {
display: block;
}
.dropdown.dropdown - submenu {
position: absolute;
left: 100 % ;
top: -7 px;
}
Save the file and test your project.Thanks