I need to create a layout that only applies to certain routes. However, when I use a Switch and separate the routes that need alternate layouts, if I try to visit a page that doesn't exist it just takes me to the layout with nothing inside of it. Here is the sample code.
<Switch>
<Route exact path="/" component={SampleComponent} />
<TokenLayout>
<Route path="/some-random-component" component={SomeRandomComponent} />
</TokenLayout>
<Route path="*" component={NotFound} />
</Switch>
the NotFound component never renders, instead it renders the TokenLayout with no children.
Any suggestions on how to resolve this?
The issue here is that the Switch component "Renders the first child <Route> or <Redirect> that matches the location." The official docs don't make it overtly clear that Route (and variations of) and Redirect are the only valid children of the Switch component. When a non-route or non-redirect component is hit, route matching stops and that component is returned and rendered. What happens next is that the nested route rendering SomeRandomComponent is inclusively matched just as if it would be by the router not inside a Switch.
Refactor the code to render the TokenLayout component inside the route.
Here are a few suggestions:
Create a wrapper component
const TokenLayoutWrapper = props => (
<TokenLayout>
<SomeRandomComponent {...props} />
</TokenLayout>
);
...
<Switch>
<Route exact path="/" component={SampleComponent} />
<Route path="/some-random-component" component={TokenLayoutWrapper} />
<Route path="*" component={NotFound} />
</Switch>
Create a Higher Order Component
const withTokenLayout = Component => props => (
<TokenLayout>
<Component {...props} />
</TokenLayout>
);
Decorate the SomeRandomComponent component export:
export default withTokenLayout(SomeRandomComponent);
...
<Switch>
<Route exact path="/" component={SampleComponent} />
<Route path="/some-random-component" component={SomeRandomComponent} />
<Route path="*" component={NotFound} />
</Switch>
Just wrap SomeRandomComponent in an inline function using the render prop, pass the route props through to SomeRandomComponent.
<Switch>
<Route exact path="/" component={SampleComponent} />
<Route
path="/some-random-component"
render={props => (
<TokenLayout>
<SomeRandomComponent {...props} />
</TokenLayout>
)}
/>
<Route path="*" component={NotFound} />
</Switch>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With