DEV Community

Cover image for How to toggle Bootstrap navbar collapse button in React without jQuery
John Otu
John Otu

Posted on • Updated on

How to toggle Bootstrap navbar collapse button in React without jQuery

Do you use Bootstrap (CSS) in React? You would've come across the advise not to add jQuery for good reason. jQuery directly manipulates the DOM so will be in conflict with React's virtual DOM which assumes it's the only Oga in charge.

But many cool Bootstrap components rely on jQuery and other Bootstrap JS plugins to work. One of such components is the navbar collapse toggle button and we can toggle it by dynamically adding (or removing) the collapse class in the nav-link's parent div.

Nav Toggle

<div class={`${isNavCollapsed ? 'collapse' : ''} navbar-collapse`} id="navbarsExample09">
  <a className="nav-link text-info" href="/contact">Support</a>
  <a className="nav-link text-info" href="/login">Login</a>
  <a href="/request-demo" className="btn btn-sm btn-info nav-link text-white" >Request demo</a>
</div>
Enter fullscreen mode Exit fullscreen mode

This seems to be the easiest way since we are still relying on Bootstrap CSS classes rather than write our own toggle functon from scratch. Using Hooks for state management and not forgetting aria-expanded boolean, we can have a TopNav component like:

import React, { useState } from 'react';
import Logo from '../images/logo_512x512.png';

const TopNav = props => {
  const [isNavCollapsed, setIsNavCollapsed] = useState(true);

  const handleNavCollapse = () => setIsNavCollapsed(!isNavCollapsed);

  return (
    <nav class="navbar navbar-expand-lg navbar-light bg-light rounded">
      <a class="navbar-brand text-info font-weight-bolder" href="/">
        <img src={Logo} alt="Logo" width="36" height="36" className="vertical-align-middle" />
        <span className="">Discounter</span>
      </a>
      <button class="custom-toggler navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded={!isNavCollapsed ? true : false} aria-label="Toggle navigation" onClick={handleNavCollapse}>
        <span class="navbar-toggler-icon"></span>
      </button>

      <div class={`${isNavCollapsed ? 'collapse' : ''} navbar-collapse`} id="navbarsExample09">
        <a className="nav-link text-info" href="/contact">Support</a>
        <a className="nav-link text-info" href="/login">Login</a>
        <a href="/request-demo" className="btn btn-sm btn-info nav-link text-white" >Request demo</a>
      </div>
    </nav>
  );
}

export default TopNav;
Enter fullscreen mode Exit fullscreen mode

Easy peasy right?

Top comments (5)

Collapse
 
dmikester1 profile image
Mike Dodge • Edited

This works to do a basic show/hide. But it doesn't give you that nice slide down and up effect that Bootstrap does. I'm on Bootstrap 5. It appears like they(Bootstrap) are adding collapsing as it's moving and that removing that class and adding show when it's done.

Collapse
 
johnotu profile image
John Otu

Bootstrap animations are powered by the JS file which we've not added in our use case. However you can implement CSS transitions and animations in React using React Transitions Group.

Substituting the appropriate class for the version of Bootstrap you are using should give the desired results.

Collapse
 
yaezah profile image
yayza

Thanks for this. Would it work the same way with Bootstrap 5 since it doesn't use jQuery? I tried to append a collapsable element using useEffect in react, but that didn't work for me.

Collapse
 
johnotu profile image
John Otu

Sorry about the late reply.

Yes it should work the same way with Bootstrap 5 with appropriate classes.

I tried to append a collapsable element using useEffect in react, but that didn't work for me.

I don't fully understand what you mean here. Could you maybe drop a snippet?

Collapse
 
tinoreyna1984 profile image
Tino Reyna

Works perfectly in React 5.2! Thanks!