Mendes
Mendes

Reputation: 18561

Bootstrap 4 NavBar with React <Link/> component

I'm trying to build a Bootstrap 4 NavBar that will use ReactJS <Link> component from react-router instead of the original <li> class.

Currently I'm having troubles building the component correctly, as at the end the ReactJS component has not the expected behaviour.

Let´s start from the original Bootstrap 4 NavBar example:

<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <a class="navbar-brand" href="#">Navbar</a>

  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#">Disabled</a>
      </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
      <input class="form-control mr-sm-2" type="text" placeholder="Search">
      <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
    </form>
  </div>
</nav>

This is being migrated to a ReactJS component as the following:

import React from 'react';
import Link from 'react-router-dom/Link';

function Menu() {
  return (
    <div>
        <nav className="navbar navbar-toggleable-md navbar-light bg-faded">
          <button className="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span className="navbar-toggler-icon"></span>
          </button>
          <a className="navbar-brand" href="#">Navbar</a>

          <div className="collapse navbar-collapse" id="navbarSupportedContent">
            <ul className="navbar-nav mr-auto">
              <span className="nav-item active">
                <Link className="nav-link" to="/">Home <span className="sr-only">(current)</span></Link>
              </span>
              <span className="nav-item">
                <Link className="nav-link" to="/counter">Counter</Link>
              </span>
              <span className="nav-item">
                <Link className="nav-link disabled" to="/about">About</Link>
              </span>
            </ul>
            <form className="form-inline my-2 my-lg-0">
              <input className="form-control mr-sm-2" type="text" placeholder="Search" />
              <button className="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
            </form>
          </div>
        </nav>
    </div>
  );
}

export default Menu;

Altough it runs, many of the formatting is lost and some features like "nav-link disabled" are not working (you can click on About and it goes to the desired page).

I'm sure I'm doing the conversion wrong. How can I fix the component code so that to reflect correctly the original behaviour without React?

Upvotes: 3

Views: 6035

Answers (3)

tobio
tobio

Reputation: 21

Maybe you got it resolved. Here's a working example with Bootstrap 4:

import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';

const AppPage = () => <h1>React Router 4 & Bootstrap 4</h1>
const HomePage = () => <h1>Welcome Home !</h1>
const AboutPage = () => <h1>About Us</h1>
const OneMorePage = () => <h1>One More Page !</h1>

const PrimaryLayout = () => (
  <div>
    <nav className="navbar navbar-expand-md navbar-dark bg-dark">
      <Link className="navbar-brand" to="/">App</Link>
      <button type="button" className="navbar-toggler" data-toggle="collapse" data-target="#navbarNav">
        <span className="navbar-toggler-icon"></span>
      </button>
      <div className="collapse navbar-collapse" id="navbarNav">
        <ul className="navbar-nav mr-auto">
          <li className="nav-item"><Link className="nav-link" to="/home">Home</Link></li>
          <li className="nav-item"><Link className="nav-link" to="/about">About</Link></li>
          <li className="nav-item"><Link className="nav-link" to="/one">More</Link></li>
        </ul>
      </div>
    </nav>
    <div className="container-fluid">
      <Switch>
        <Route path="/" exact component={AppPage} />
        <Route path="/home" component={HomePage} />
        <Route path="/about" component={AboutPage} />
        <Route path="/one" component={OneMorePage} />
      </Switch>
    </div>
  </div>
)

const App = () => (
  <BrowserRouter>
    <PrimaryLayout />
  </BrowserRouter>
)

render(<App />, document.getElementById('root'))

Upvotes: 2

cbrandolino
cbrandolino

Reputation: 5883

For this particular use case, there's an easy solution.

Simply add this to your css:

.nav-link.disabled { pointer-events: none }.

That said, I'd strongly recommend to use a library of bootstrap-based react components on the long term. I personally like https://reactstrap.github.io/.

Upvotes: 1

mrinalmech
mrinalmech

Reputation: 2175

The problem is Bootstrap has a Javascript component as well which will not work in React as it clashes with React's Javascript. The CSS portion works which is what you are seeing.

You should use something like React-Bootstrap- https://react-bootstrap.github.io/. These are all the Bootstrap components written as React components so you can use them in the standard React manner by importing and using them in your JSX.

Upvotes: 0

Related Questions