17

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

Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318
Complexity
  • 5,148
  • 3
  • 28
  • 76

3 Answers3

31

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>
Creaforge
  • 4,493
  • 24
  • 33
Taras Yaremkiv
  • 3,205
  • 6
  • 25
  • 48
  • 1
    ` // Default Route - FAILS ` Switch inside Switch is failing to load the Default Route.. Any idea on how to achieve the default Route when using switch inside switch? – Nitin Kumar Jul 27 '18 at 21:30
  • Sorry for the formatting. I am unable to beautify it in comments – Nitin Kumar Jul 27 '18 at 21:31
  • 3
    @NitinKumar ```All children of a should be or elements. Only the first child to match the current location will be rendered.``` according to [official docs](https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Switch.md), so avoid using nested switches – Taras Yaremkiv Jul 31 '18 at 08:24
13

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>
Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318
0

I think NotFound page is rendered because of <Route path="*" component={NotFound} /> rule. Path property of the Router accepts Any valid URL path that path-to-regexp understands. So '*' means zero or more parameter matches

Serg
  • 76
  • 4