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!