4

I have a Route file which contains multiple routes like this

const RouteUI = ({context}) =>
  <Switch>
  <React.Fragment>

    <SDPRouteUI context={context} />

    <SDPMRouteUI context={context} />

    <ACRouteUI context={context} />

    <DCRouteUI context={context} />

    <Route path=""
      render={() =>
        <NotFound context={context} />
      }
    />

  </React.Fragment>

  </Switch>

The NotFound component is getting rendered on every page,even though it is inside switch.

SDPRouteUI,SDPMRouteUI..etc are other route files like

const SDPRouteUI = ({context}) =>
  <Switch>
    <Route exact path='/sdp/account'
      render={() =>
        <SDPAccountPageSF context={context} />
      }
    />

    <Route exact path='/sdp/activate/back'
      render={() =>
        <SDPActivateBackSF context={context} />
      }
    />
<Switch>
Shubham Chopra
  • 1,678
  • 17
  • 30

3 Answers3

2

The Top level Switch statement doesn't work because the first element being not a Route is automatically rendered which in your case is React.Fragment. Even if you move Switch element to between React.Fragment it wouldn't work as the other default component would render.

In order to handle nested routes you need to have a Provider/Consumer pattern. Refer this answer to handle 404 Routes correctly

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • @ShubhamChopra PLease let me know if the above answer helped you or not – Shubham Khatri Feb 14 '19 at 05:34
  • Not exactly but was useful.Thanks – Shubham Chopra Feb 22 '19 at 13:57
  • 1
    Your answer combined with [this SO question](https://stackoverflow.com/questions/50155909/how-to-use-context-api-with-react-router-v4) saved my ass. Your answer helped me to get a better idea. My problem was in that only works right with components as its immediate children. – MickeyDickey Jan 15 '22 at 23:54
  • Agree with @MickeyDickey - this is key `... only works right with components as its immediate children` – StudioTime Apr 20 '22 at 07:30
1

It's fairly simple to achieve 404 in react router. Inside react router component, create a route without path defined. And make sure to place the code at the bottom of all routes, so that router will check all the routes and fallback if no match found.

<Router>
   <Link to="/users">Users</Link>
   <Link to="/search?q=react">Search</Link>
   <Route exact path="/about" component={AboutPage} />
   <Route exact path="/search" component={SearchPage} />
   <Route component={NoMatchPage} />
</Router>

Visit any random URL, you will see a simple 404 page. But wait, let's check whether other pages work normally without breaking. It won't! Check on about link, you will see both about and 404 page get rendered. Because first router matched the exact route for /about path and then it traverses to the bottom and load the 404 route since this route have no path defined. React router provide a component called Switch to break once a route get resolved and not load any other route component below it. Its fairly easy to implement. Enclose all the route inside Switch component. lets do it and make the 404 page works without error.

import { Link, BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const App = () => {
  return (
    <section className="App">
      <Router>
        ...
        <Switch>
          <Route exact path="/" component={IndexPage} />
          ...
          <Route exact path="/search" component={SearchPage} />
          <Route component={NoMatchPage} />
        </Switch>
      </Router>
    </section>
  );
};

...

This Switch component will check for the matching route, if a route is already matched, it breaks checking the next routes. By this way, we will avoid rendering 404 route for all pages.

ZiaUllahZia
  • 1,072
  • 2
  • 16
  • 30
0

<Route component={NotFound} /> , maybe fix your problem

If u define any route without "path" prop, the switch component will automatically move to the NotFound component.

<Route exact strict component ={NotFound} />, can be more useful. For exact Route.

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
Jayakar
  • 33
  • 2
  • 7