0

I have created a new route inside of 'Form' but cannot do it without affecting the 'Businesses' route I had previously created (the 'Business' route will not appear at all). I read the documentation but couldn't really figure out how to solve this problem but I'm assuming it's because of the two 'exact path'.

<Switch>
  <Route exact path="/"> 
    <Form />
  </Route>
  <Route path="/booking">
    <Booking />
  </Route>
</Switch>

//inside of <Form/>

<Switch>
  <Route exact path ="/"> 
    <Selection/>
  </Route>
  <Route path ="/businesses/:businessesId"> 
    <Businesses/>
  </Route>
</Switch>  
uber
  • 4,163
  • 5
  • 26
  • 55

2 Answers2

2

Lets first think about what logic is currently in place. <Switch> does exactly what you might guess (similar to a normal switch statement), and it returns the first <Route> match inside. To help visualize, lets remove the JSX and just use logical operators.

You currently have the equivalent to this pseudo code:

switch(path) {
  case '/':
    switch(path) {
      case '/':
        return 'Form Component';
      case '/businesses/*':
        return 'Businesses Component';
    }
  case '/booking'
    return 'Booking Component';
  default:
    return null;
}

Can you see the problem?

Both the outer switch and the nested switch are trying to match the same path. Since the nested switch only gets triggered when the path is exactly /, the inner switch can only ever match that as well. As soon as you change the path to /businesses, the outer switch no longer matches /, so your nested switch never gets a chance to match the path.

There are a few ways to fix this, and the correct way will depend on your specific needs and preferences.

The first is do follow something like what @faithfull has described. Put all of your <Route>'s on the same level. This would change your logic to this pseudo code:

switch(path) {
  case '/':
    return 'Form Component';
  case '/businesses/*':
    return 'Businesses Component';
  case '/booking'
    return 'Booking Component';
  default:
    return null;
}

However this won't work if your requirement is to have nested routes. If you need the second switch to be nested, then simply remove the exact prop from the outer switch. But this alone will cause other issues. A <Switch> only renders its first match. So removing the exact prop will cause the / path to always be the first match. You'll need to move this to the bottom of your switch so that the other <Route>'s have a chance to match first:

<Switch>
  <Route path="/booking">
    <Booking />
  </Route>
  <Route path="/"> 
    <Form />
  </Route>
</Switch>

Then you can leave the nested router as is and you should be good to go!

Brian Thompson
  • 13,263
  • 4
  • 23
  • 43
0

You should probably do something like:

<Switch>
  <Route exact path="/"> 
    <Form />
  </Route>
  <Route path="/booking">
    <Booking />
  </Route>
  <Route path ="/businesses/:businessesId"> 
    <Businesses />
  </Route>
</Switch>

And then in your Form.tsx

import Selection from '...';
class Form extends React.Component {
  render() {
    return (
      {/*some other Form jsx*/}
      {Selection}
    );
  }
}
faithfull
  • 431
  • 6
  • 8