React Router v4 renders multiple routes

I'm creating an SPA and I'm trying to setup Routing in the application using the react-router-dom package version 4.1.1.

My Route Definition is below:

<BrowserRouter>
  <div>
    <Route exact path="/" component={Login} />
    <Route path="/login" component={Login} />
    <Route path="404" component={NotFound} />
    <Route path="*" component={NotFound} />
  </div>
</BrowserRouter>

Basically, I want to setup routing so that any request to a page for which no route is defined goes to the {NotFound} component.

How can this be achieved? The solution above renders both the Login and the NotFound component when requesting the /login page.

Kind regards


Solution 1:

here's an example from official tutorial, how to avoid rendering multiple routes

import { Switch, Route } from 'react-router'

<Switch>
  <Route exact path="/" component={Home}/>
  <Route path="/about" component={About}/>
  <Route path="/:user" component={User}/>
  <Route component={NoMatch}/>
</Switch>

Solution 2:

Make use of Switch to render the first match of the route, You need to import Switch before using

import {Switch} from 'react-router';

<BrowserRouter>
  <Switch>
    <Route exact path="/" component={Login} />
    <Route path="/login" component={Login} />
    <Route path="404" component={NotFound} />
    <Route path="*" component={NotFound} />
  </Switch>
</BrowserRouter>

According to the docs

<Switch> is unique in that it renders a route exclusively. In contrast, every <Route> that matches the location renders inclusively.

Now, if we’re at /login, <Switch> will start looking for a matching <Route>. <Route path="/login"/> will match and <Switch> will stop looking for matches and render <Login>. otherwise route matches /login with /login and * and renders both the routes

However, when using Switch the order of Routes matter, make sure that you are adding the prefix Routes after the other Routes. For e.g. '/home' must be after '/' in the Route order or else, you could make use of the exact prop

 <Switch>
    <Route exact path="/" component={Login} />
    <Route path="/home" component={Home} />
  </Switch>