CONCON
CONCON

Reputation: 91

React-bootstrap navbar with React Router

I have looked at various answers related to the subject, but the issue seem to persist. Would be happy if some concrete solution is available.

I am trying to render a navbar using react-bootstrap and trying to route it using react-router. It does not seem to work on the first click. When the page is forced the components get loaded.

Here are the relevant files.

MyAppNavbar,js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Nav, NavDropdown, Navbar, Container, Alert } from "react-bootstrap";
import { Link } from 'react-router-dom';
import Routes from './Routes';

class MyAppNavbar extends Component {

    render() {
        return (
            <React.Fragment>
                <Navbar collapseOnSelect expand="lg" bg="dark" fixed="top" variant="dark" >
                    <Navbar.Brand as={Link} to="/" >React-Bootstrap</Navbar.Brand>
                    <Navbar.Toggle aria-controls="responsive-navbar-nav" />
                    <Navbar.Collapse id="responsive-navbar-nav">
                        <Nav activeKey={window.location.pathname} variant="pills">
                            <Nav.Item href="/">
                                <Nav.Link as={Link} to="/" eventKey="/home" title="Home">
                                    Home
                            </Nav.Link>
                            </Nav.Item>
                            <Nav.Item>
                                <Nav.Link as={Link} to="/about" title="About">
                                    About
                            </Nav.Link>
                            </Nav.Item>
                            <Nav.Item>
                                <Nav.Link as={Link} to="/category" eventKey="category" title="Category">
                                    Category
                            </Nav.Link>
                            </Nav.Item>

                            <NavDropdown title="Products" id="nav-dropdown">
                                <NavDropdown.Item>
                                    Basic Pricing
                            </NavDropdown.Item>

                                <NavDropdown.Item>
                                    Corporate
                            </NavDropdown.Item>
                                <NavDropdown.Divider />

                                <NavDropdown.Item> Enterprise pricing
                            </NavDropdown.Item>
                            </NavDropdown>
                        </Nav>
                    </Navbar.Collapse>
                </Navbar>
                <Routes />
            </React.Fragment>
        );
    }
}
export default MyAppNavbar;

Routes.js

import React from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Category from './Category';
import Products from './Products';
import Home from "./Home";
import About from "./About";
import NotFound from './NotFound'

const Routes = () =>
    <Router>
        <Switch>
            <Route exact path='/'>
                <Home />
            </Route>
            <Route path='/about'>
                <About />
            </Route>
            <Route path='/category'>
                <Category />
            </Route>
            <Route path='/products'>
                <Products />
            </Route>
            <Route >
                <NotFound />
            </Route>
        </Switch>
    </Router>

export default Routes;

App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Routes from './website/Routes';
import MyAppNavbar from "./website/MyAppNavbar";

const App = () => 
    <React.Fragment>
        <MyAppNavbar />
        <Routes/>
    </React.Fragment>
export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

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

Upvotes: 5

Views: 6937

Answers (2)

75ntamas
75ntamas

Reputation: 320

I run to the same issue, here is my fix: Use react-router-bootstrap.

I think you should change only MyAppNavbar.js:

First in the top of MyAppNavBar.js import LinkContainer from react-router-bootstrap:

import { LinkContainer } from 'react-router-bootstrap';

Then change all the child elements of Nav element from this:

<Nav.Item href="/">
  <Nav.Link as={Link} to="/" eventKey="/home" title="Home">
    Home
  </Nav.Link>
</Nav.Item>

to this:

<LinkContainer to="/">
  <Nav.Link>
    Home
  </Nav.Link>
</Nav.Item>

I hope it helps.

Upvotes: 0

lala
lala

Reputation: 1439

Try these fixes:-

Since you use NavLink inside MyAppNavBar.js, then it will need BrowserRouter from react-router-dom to be functional.

Then you can either do:-

  • Fixes 1 - Wrap everything in App.js with BrowserRouter or,
  • Fixes 2 - You can just remove BrowserRouter in Routes.js

You just need ONE BrowserRouter anyway

Fixes 1

  • Remove BrowserRouter from both index.js & Routes.js

  • add & wrap everything inside App.js with BrowserRouter

  • 'index.js':-

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(<App/>, document.getElementById('root')
);
  • Routes.js:-
import React from 'react';
import { Switch, Route, Link } from 'react-router-dom';
import Category from './Category';
import Products from './Products';
import Home from "./Home";
import About from "./About";
import NotFound from './NotFound'

const Routes = () =>
    <Switch>
      <Route exact path='/'>
        <Home />
      </Route>
      <Route path='/about'>
        <About />
      </Route>
      <Route path='/category'>
        <Category />
      </Route>
      <Route path='/products'>
        <Products />
      </Route>
      <Route >
        <NotFound />
      </Route>
    </Switch>

export default Routes;
  • App.js:-
import React, { Component } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import Routes from './website/Routes';
import MyAppNavbar from "./website/MyAppNavbar";

const App = () => 
    <Router>
        <MyAppNavbar />
        <Routes/>
    </Router>
export default App;

Fixes 2

Remove BrowserRouter from Routes.js

  • Routes.js:-
import React from 'react';
import { Switch, Route, Link } from 'react-router-dom';
import Category from './Category';
import Products from './Products';
import Home from "./Home";
import About from "./About";
import NotFound from './NotFound'

const Routes = () =>
    <Switch>
      <Route exact path='/'>
        <Home />
      </Route>
      <Route path='/about'>
        <About />
      </Route>
      <Route path='/category'>
        <Category />
      </Route>
      <Route path='/products'>
        <Products />
      </Route>
      <Route >
        <NotFound />
      </Route>
    </Switch>

export default Routes;

Upvotes: 1

Related Questions