Collapsing navbar using bootstrap in react-typescript

Viewed 518

I am trying to create a collapsible navbar using bootstrap in my react-typescript project (see my code below).

  return (
    <nav className="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
      <div className="container-fluid">
        <img className="mb-0" src={logoNav} alt="" width="200" height="50" />
        <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
          <span className="navbar-toggler-icon"></span>
        </button>
        <div className="collapse navbar-collapse">
          <ul className="navbar-nav me-auto mb-2 mb-md-0">
            <li className="nav-item">
              <a className="nav-link active" aria-current="location" href="/home">Home</a>
            </li>
            <li className="nav-item">
              <a className="nav-link active" href="/consultAndReserve">Consulter et réserver</a>
            </li>
            <li className="nav-item">
              <a className="nav-link active" href="/myReservations">Mes réservations</a>
            </li>
            <li className="nav-item">
              <a className="nav-link active" href="/profile">Profile</a>
            </li>
          </ul>
          <button className=" d-flex btn btn-outline-danger" type="submit" onClick={logOutAndReturnToLoginPage}>Se déconnecter</button>
        </div>
      </div>
    </nav>
  )

I am using the boostrap navbar example code (see below for example) and am able to get the navbar to render correctly, however when I click the navbar-toggler icon nothing happens because I don't have the following script included.

<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">Fixed navbar</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarCollapse">
      <ul class="navbar-nav me-auto mb-2 mb-md-0">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="#">Home</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled">Disabled</a>
        </li>
      </ul>
    </div>
  </div>
</nav>



    <script src="../assets/dist/js/bootstrap.bundle.min.js"></script>

How would one implement such script using react-typescript (is it even possible)?

2 Answers

When you work with React and Bootstrap, I would recommend you to use the library "react-bootstrap". It defines components, which implement bootstrap classes and bootstrap js code. It's abstracted away, so you don't need to handle it by yourself. When you look into: https://react-bootstrap.github.io/components/navbar/#overview you will notice many transitions (from bootstrap classes to React components and their props):

<Navbar bg="light" expand="lg">
  <Container>
    <Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
    <Navbar.Toggle aria-controls="basic-navbar-nav" />
    <Navbar.Collapse id="basic-navbar-nav">
      <Nav className="me-auto">
        <Nav.Link href="#home">Home</Nav.Link>
        <Nav.Link href="#link">Link</Nav.Link>
        <NavDropdown title="Dropdown" id="basic-nav-dropdown">
          <NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
          <NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
          <NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
          <NavDropdown.Divider />
          <NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
        </NavDropdown>
      </Nav>
    </Navbar.Collapse>
  </Container>
</Navbar>

With react-bootstrap the javascript part of bootstrap is automatically installed. CSS part can be included via the CDN or local script. Or you can just install bootstrap as well, when you plan to customize Sass files: https://react-bootstrap.netlify.app/getting-started/introduction/#installation

If you don't want to use react-bootstrap for some reason (I couldn't think of any), then you need to link the scripts in your index.html file.

As for every package when working with Typescript, you need to install the appropriate @types packages as well: @types/bootstrap, @types/react-bootstrap etc.

Make sure you installed bootstrap, e.g. "npm install bootstrap" and be sure to import both the css and js in your index.js file:

import '../node_modules/bootstrap/dist/css/bootstrap.css';
import '../node_modules/bootstrap/dist/js/bootstrap.bundle';

Also if you're working with Bootstrap 5.1.3 in React and Redux-Toolkit. By adding a simple span tag like this to the Link (Route) component, like this: <span data-bs-target="#navbarNav" data-bs-toggle="collapse">Home</span>, allows the bootstrap collapse and link route to work simultaneously and seamlessly.

*If you see a blinking effect, you can fix by adding bootstrap screen size display tags e.g.:

<Link to={'/home'} className="nav-link d-sm-none"><span data-bs-target="#navbarNav" data-bs-toggle="collapse">Home</span></Link>
<Link to={'/home'} className="nav-link d-none d-sm-block">Home</Link>

*No extra JS or Jquery required

*It should work with most applications using Bootstrap 5.0

<nav className="navbar navbar-expand-lg navbar-dark bg-dark navbar-expand-sm fixed-top">
   <div className="container">

      <button className="navbar-toggler" type="button"
          data-bs-toggle="collapse" data-bs-target="#navbarNav"
          aria-controls="navbarNav" aria-expanded="false"
          aria-label="Toggle navigation">
      <span className="navbar-toggler-icon"></span>
      </button>
                    
      <div className="collapse navbar-collapse" id="navbarNav">
          <ul className="navbar-nav mt-2 mt-sm-0">
              <li className="nav-item">
                  // 2 tags below for different screen sizes
                  <Link to={'/home'} className="nav-link d-sm-none"><span data-bs-target="#navbarNav" data-bs-toggle="collapse">Home</span></Link>
                  <Link to={'/home'} className="nav-link d-none d-sm-block">Home</Link>
              </li>
              <li className="nav-item">
                  // 2 tags below for different screen sizes
                  <Link to={'/counter'} className="nav-link d-sm-none"><span data-bs-target="#navbarNav" data-bs-toggle="collapse">Counter</span></Link>
                  <Link to={'/counter'} className="nav-link d-none d-sm-block">Counter</Link>
              </li>
          </ul>
      </div>

   </div>
</nav>
Related