5

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')
);
2
  • 1
    I don't think you need to re-declare BrowserRouter in Routes.js since you already did that in index.js. Will there be any changes then? Commented Nov 22, 2020 at 15:04
  • I realized the issue.. It was due to the refactoring of code between index.js and app to wrap the router. It was removed later. The issue though still persists Commented Dec 3, 2020 at 8:26

2 Answers 2

1

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;
Sign up to request clarification or add additional context in comments.

1 Comment

I got this error: "export 'Switch' (imported as 'Switch') was not found in 'react-router-dom'"
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.