Responsive & Fast Primary Navigation Menu For ReactJS Application

In this article, we will be creating a simple yet fast, animated and responsive navigation menu for ReactJS which can work perfectly for your desktop/laptop users as well as also for your mobile phone users.

Creating a perfect navigation menu might look simple at first, but comes with its own challenges. Making it look perfect on all form-factor is definitely a challenge. The steps we are going to follow are simple. Once done, I’ll also provide you with some ideas about how you can customize it to suite you better.

Steps

  1. Install React Router
  2. Design Navigation Menu using Flexbox CSS
  3. Utilizing CSS media queries to handle responsiveness
  4. Avail the power of React to create a functional hamburger toggle button

1. Install React Router

For efficient routing, we will need to use the official react-router-dom package. If not already installed, go ahead and install the React Router package by executing the npm install as depicted below.

$ npm install react-router-dom

First, let’s go ahead and look at the structure we have used in the project.

As you can see, our App.js component has a two primary containers wrapped inside a BrowserRouter,

  1. A nav tag hosts the navigation bar with all the links and brand URL
  2. A secondary custom component AllRoutes which is basically list of all the possible routes; more details later.

The navigation bar and the list of links are aligned using basic flex box properties as can be seen below with a by default hidden hamburger button.

3. Utilizing CSS media queries to handle responsiveness

Now the magic code behind CSS media queries transforms the navigation bar completely. Main transformation is applied to the <div> tag with class navbar-links which contains the navigation links. It’s position is changed to absolute with fixed width of 75% and margin of -75% to make it disappear at right side (yes we set the float to right). Also we unhide hamburger button. Here is the code:

@media only screen and (max-width: 992px) {
  .navbar-toggler {
    display: block;
  }

  ul.navbar-links {
    margin-right: 0;
    position: absolute;
    width: 75%;
    background: whitesmoke;
    z-index: 99;
    margin-top: 3rem;
    float: right;
    right: 0;
    height: 100vh;
    transition: all ease-in-out 0.3s;
    align-self: flex-start;
    border-top: 2px solid maroon;
  }

  ul.links-list {
    display: flex;
    flex-direction: column;
    padding-left: 0;
  }

  .navbar-links.menu-collapse {
    margin-right: -75%;
    width: 0;
    overflow: hidden;
  }

  li.nav-item {
    padding-left: 20px;
    padding-top: 10px;
    padding-bottom: 10px;
    margin-left: 0;
  }

  li.nav-item a.nav-link {
      padding: 10px 20px;
  }

  .menu-collapse {
    margin-right: -75%;
    width: 0;
    overflow: hidden;
  }
}

4. Avail the power of React and create a functional hamburger toggle button

The last step is rather very simple. We now have a hamburger button that we need to add functionality to. We will use onClick action on the button to attach a function call to the click event. In the function call, we will just toggle menu-collapse class which basically hides and shows the navbar.

The JSX:

<button onClick={(e) => { handleNavbarButton(e); }} className='navbar-toggler'>
   <span className='navbar-toggler-icon'></span>
</button>
<div ref={navbarLinks} className='navbar-links menu-collapse'>
  <ul className='links-list'>
      // ... all the list items
   </ul>
</div>

The handleNavbarButton function:

const navbarLinks = useRef(null);
const handleNavbarButton = (e) => {
  navbarLinks.current.classList.toggle('menu-collapse');
};

const hideNavMenu = () => {
  if (!navbarLinks.current.classList.contains('menu-collapse')) {
    navbarLinks.current.classList.add('menu-collapse');
  }
}

Bonus: Closing the Navigation Menu Programmatically

This is a problem that you will face when user clicks on any of the link inside the navigation bar on cell phone. The navigation does happen but the right navigation bar is not closed. Well, don’t worry its just a few lines of code to make sure that happens.

Remember the custom AllRoutes component that we used? The component houses all the possible Routes which users might want to navigate by clicking on the navigation links. Here is how the AllRoutes component looks.

function AllRoutes({ hideMenu }) {

  let location = useLocation();
  useEffect(() => {
    hideMenu();
  }, [location]);

  return (
    <Switch>
      <Route path="/about" component={About}>
      </Route>
      <Route path="/contact" component={Contact}>
      </Route>
      <Route path="/" component={Home}>
      </Route>
    </Switch>
  );
}

Explanation: We are using basic Switch and Route tag part of react-router which matches the navigation links clicked and activate the required component. As it is a functional component, we use useEffect hook to check for the current location of the page. As soon as the location changes, we call hideMenu() function which in turns calls hideNavMenu function in App component and ensures that the navigation menu is closed.

Something to Note: Remember, the Home component should be at last as the path “/” is true for all the three Routes and putting it at first will show confusing results with two routes rendered at once when activating about or contact routes.

That’s it! You should have a proper working animated and responsive navigation menu for your website! You can check the whole source code below:

Additional Resources

Hope this act as a reference to you. In case of doubt, confusion or feedback drop down a comment below or you can also use the contact us section! Happy Coding!

GC

About the Author: Gaurav Chouhan

Gaurav is an independent senior software consultant and trainer based out of India with more than 5 years of experience in cloud computing specifically on Microsoft Azure, full-stack development on .net core and angular and mobile programming on Android and UWP. For business opportunity, please use the contact section.

Leave a Reply

%d bloggers like this: