How to create a Responsive Sidebar with dropdown menu in ReactJS?

10 Feb, 2021
A sidebar is an important element of a website’s design since it allows users to quickly visit any section within a site.
A glimpse of the project: 
Prerequisite:
npmcreate-react-appreact-router-domuseState React hooks
npm
create-react-app
react-router-dom
useState React hooks
Basic Setup: You will start a new project using create-react-app so open your terminal and type:
npx create-react-app react-sidebar-dropdown
Now go to your react-sidebar-dropdown folder by typing the given command in the terminal:
cd react-sidebar-dropdown
Required module: Install the dependencies required in this project by typing the given command in the terminal.
npm install react-router-dom
npm install --save styled-components
npm install --save react-icons
Now create the components folder in src then go to the components folder and create three files Sidebar.js, SidebarData.js, and SubMenu.js. 
Create one more folder in src by the name pages and in pages create files by the name AboutUs.js, ContactUs.js, Events.js, Services.js, Support.js.
Project Structure: The file structure in the project will look like this.
Filename- Sidebar.js: Open & Close Sidebar View, that’s where the role of useState() hook comes into play.
We create a state with the first element sidebar as an initial state having a value of the false and the second element as function setSidebar() for updating the state. Then a function is created by the name showSidebar() which sets the value of the sidebar opposite to its present value whenever it is called. 
This function is used with the menu bars icon and cross icon with the help of onClick() function. When we click on the bars icon to see the sidenav links it sets the value of the state to true, displays the sidebar and a cross icon appears in place of the bars’ icon. When we want to close the sidebar we simply click on the cross icon and it gets replaced with a bar icon after closing the sidebar because now the value of the state is set to false.
Javascript
import React, { useState } from "react";import styled from "styled-components";import { Link } from "react-router-dom";import * as FaIcons from "react-icons/fa";import * as AiIcons from "react-icons/ai";import { SidebarData } from "./SidebarData";import SubMenu from "./SubMenu";import { IconContext } from "react-icons/lib";  const Nav = styled.div`  background: #15171c;  height: 80px;  display: flex;  justify-content: flex-start;  align-items: center;`;  const NavIcon = styled(Link)`  margin-left: 2rem;  font-size: 2rem;  height: 80px;  display: flex;  justify-content: flex-start;  align-items: center;`;  const SidebarNav = styled.nav`  background: #15171c;  width: 250px;  height: 100vh;  display: flex;  justify-content: center;  position: fixed;  top: 0;  left: ${({ sidebar }) => (sidebar ? "0" : "-100%")};  transition: 350ms;  z-index: 10;`;  const SidebarWrap = styled.div`  width: 100%;`;  const Sidebar = () => {  const [sidebar, setSidebar] = useState(false);    const showSidebar = () => setSidebar(!sidebar);    return (    <>      <IconContext.Provider value={{ color: "#fff" }}>        <Nav>          <NavIcon to="#">            <FaIcons.FaBars onClick={showSidebar} />          </NavIcon>          <h1            style={{ textAlign: "center",                      marginLeft: "200px",                      color: "green" }}          >            GeeksforGeeks          </h1>        </Nav>        <SidebarNav sidebar={sidebar}>          <SidebarWrap>            <NavIcon to="#">              <AiIcons.AiOutlineClose onClick={showSidebar} />            </NavIcon>            {SidebarData.map((item, index) => {              return <SubMenu item={item} key={index} />;            })}          </SidebarWrap>        </SidebarNav>      </IconContext.Provider>    </>  );};  export default Sidebar;
Filename- SidebarData.js:
Javascript
import React from "react";import * as FaIcons from "react-icons/fa";import * as AiIcons from "react-icons/ai";import * as IoIcons from "react-icons/io";import * as RiIcons from "react-icons/ri";  export const SidebarData = [  {    title: "About Us",    path: "/about-us",    icon: <AiIcons.AiFillHome />,    iconClosed: <RiIcons.RiArrowDownSFill />,    iconOpened: <RiIcons.RiArrowUpSFill />,      subNav: [      {        title: "Our Aim",        path: "/about-us/aim",        icon: <IoIcons.IoIosPaper />,      },      {        title: "Our Vision",        path: "/about-us/vision",        icon: <IoIcons.IoIosPaper />,      },    ],  },  {    title: "Services",    path: "/services",    icon: <IoIcons.IoIosPaper />,    iconClosed: <RiIcons.RiArrowDownSFill />,    iconOpened: <RiIcons.RiArrowUpSFill />,      subNav: [      {        title: "Service 1",        path: "/services/services1",        icon: <IoIcons.IoIosPaper />,        cName: "sub-nav",      },      {        title: "Service 2",        path: "/services/services2",        icon: <IoIcons.IoIosPaper />,        cName: "sub-nav",      },      {        title: "Service 3",        path: "/services/services3",        icon: <IoIcons.IoIosPaper />,      },    ],  },  {    title: "Contact",    path: "/contact",    icon: <FaIcons.FaPhone />,  },  {    title: "Events",    path: "/events",    icon: <FaIcons.FaEnvelopeOpenText />,      iconClosed: <RiIcons.RiArrowDownSFill />,    iconOpened: <RiIcons.RiArrowUpSFill />,      subNav: [      {        title: "Event 1",        path: "/events/events1",        icon: <IoIcons.IoIosPaper />,      },      {        title: "Event 2",        path: "/events/events2",        icon: <IoIcons.IoIosPaper />,      },    ],  },  {    title: "Support",    path: "/support",    icon: <IoIcons.IoMdHelpCircle />,  },];
Filename- SubMenu.js: The logic for Dropdown links, again done with useState() hooks.
We create a state with the first element subnav as an initial state having a value of the false and the second element as function setSubnav() for updating the state. Then a function is created by the name showSubnav() which sets the value of subnav opposite to its present value whenever it is called.
This function is used with the open icon and close icon. When we click on the open icon to see the dropdown links it sets the value of the state to true, displays the dropdown menu and a close icon appears in place of the open icon. When we want to close the dropdown links we simply click on the close icon and it gets replaced with an open icon after closing the dropdown menu because now the value of the state is set to false.
As every sidelink is not having a dropdown menu, it first checks if a sideline has a property of subNav defined with it from the object array that we made in the SidebarData.js file. If that property exists then it executes the above logic otherwise the sidelinks appear normally without any open and close icons.
Javascript
import React, { useState } from "react";import { Link } from "react-router-dom";import styled from "styled-components";  const SidebarLink = styled(Link)`  display: flex;  color: #e1e9fc;  justify-content: space-between;  align-items: center;  padding: 20px;  list-style: none;  height: 60px;  text-decoration: none;  font-size: 18px;    &:hover {    background: #252831;    border-left: 4px solid green;    cursor: pointer;  }`;  const SidebarLabel = styled.span`  margin-left: 16px;`;  const DropdownLink = styled(Link)`  background: #252831;  height: 60px;  padding-left: 3rem;  display: flex;  align-items: center;  text-decoration: none;  color: #f5f5f5;  font-size: 18px;    &:hover {    background: green;    cursor: pointer;  }`;  const SubMenu = ({ item }) => {  const [subnav, setSubnav] = useState(false);    const showSubnav = () => setSubnav(!subnav);    return (    <>      <SidebarLink to={item.path}       onClick={item.subNav && showSubnav}>        <div>          {item.icon}          <SidebarLabel>{item.title}</SidebarLabel>        </div>        <div>          {item.subNav && subnav            ? item.iconOpened            : item.subNav            ? item.iconClosed            : null}        </div>      </SidebarLink>      {subnav &&        item.subNav.map((item, index) => {          return (            <DropdownLink to={item.path} key={index}>              {item.icon}              <SidebarLabel>{item.title}</SidebarLabel>            </DropdownLink>          );        })}    </>  );};  export default SubMenu;
Now we are completed with the components folder now we manipulate the pages. Edit various pages for the sidebar in the project in src/pages:
Filename- AboutUs.js:
Javascript
import React from "react";  export const AboutUs = () => {  return (    <div className="home">      <h1>GeeksforGeeks About us</h1>    </div>  );};  export const OurAim = () => {  return (    <div className="home">      <h1>GeeksforGeeks Aim</h1>    </div>  );};  export const OurVision = () => {  return (    <div className="home">      <h1>GeeksforGeeks Vision</h1>    </div>  );};
Filename- ContactUs.js:
Javascript
import React from "react";  const Contact = () => {  return (    <div className="contact">      <h1>GeeksforGeeks Contact us</h1>    </div>  );};  export default Contact;
Filename- Events.js:
Javascript
import React from "react";  export const Events = () => {  return (    <div className="events">      <h1>GeeksForGeeks Events</h1>    </div>  );};  export const EventsOne = () => {  return (    <div className="events">      <h1>GeeksforGeeks Event1</h1>    </div>  );};  export const EventsTwo = () => {  return (    <div className="events">      <h1>GeeksforGeeks Event2</h1>    </div>  );};
Filename- Services.js:
Javascript
import React from "react";  export const Services = () => {  return (    <div className="services">      <h1>GeeksforGeeks Services</h1>    </div>  );};  export const ServicesOne = () => {  return (    <div className="services">      <h1>GeeksforGeeks Service1</h1>    </div>  );};  export const ServicesTwo = () => {  return (    <div className="services">      <h1>GeeksforGeeks Service2</h1>    </div>  );};  export const ServicesThree = () => {  return (    <div className="services">      <h1>GeeksforGeeks Service3</h1>    </div>  );};
Filename- Support.js:
Javascript
import React from "react";  const Support = () => {  return (    <div className="support">      <h1>GeeksforGeeks Support us</h1>    </div>  );};  export default Support;
All the pages and components are ready now we have to call them one by one in our App.js file.
Filename- App.js:
Javascript
import "./App.css";import Sidebar from "./components/Sidebar";import { BrowserRouter as Router, Switch, Route } from "react-router-dom";import { AboutUs, OurAim, OurVision } from "./pages/AboutUs";import {  Services,  ServicesOne,  ServicesTwo,  ServicesThree,} from "./pages/Services";import { Events, EventsOne, EventsTwo } from "./pages/Events";import Contact from "./pages/ContactUs";import Support from "./pages/Support";function App() {  return (    <Router>      <Sidebar />      <Switch>        <Route path="/about-us" exact component={AboutUs} />        <Route path="/about-us/aim" exact component={OurAim} />        <Route path="/about-us/vision" exact component={OurVision} />        <Route path="/services" exact component={Services} />        <Route path="/services/services1" exact component={ServicesOne} />        <Route path="/services/services2" exact component={ServicesTwo} />        <Route path="/services/services3" exact component={ServicesThree} />        <Route path="/contact" exact component={Contact} />        <Route path="/events" exact component={Events} />        <Route path="/events/events1" exact component={EventsOne} />        <Route path="/events/events2" exact component={EventsTwo} />        <Route path="/support" exact component={Support} />      </Switch>    </Router>  );}  export default App;
Filename- App.css: modify the CSS according to you.
HTML
* {  box-sizing: border-box;  margin: 0;  padding: 0;}.home,.services,.reports,.contact,.events,.support {  display: flex;  margin-left: 260px;  font-size: 2rem;}
Run the Project: Save all files and start the server by using the below command.
npm start
Output:
React-Questions
Technical Scripter 2020
ReactJS
Technical Scripter
Web Technologies
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Axios in React: A Guide for Beginners
ReactJS setState()
How to pass data from one component to other component in ReactJS ?
Re-rendering Components in ReactJS
ReactJS defaultProps
Installation of Node.js on Linux
Top 10 Projects For Beginners To Practice HTML and CSS Skills
Difference between var, let and const keywords in JavaScript
How to insert spaces/tabs in text using HTML/CSS?
Differences between Functional Components and Class Components in React