I'm going to start by linking the research I've done.
- Nested routes with react router v4 - Question
- React Router 4 Documentation
- Why can I not nest Route components in react-router 4.x? - Question
- How to nest routes in React Router v4? - Question
- Getting Started with React Router v4 - The Meteor Chef
- A Simple React Router v4 Tutorial
- Warning: You should not use and in the same route;
<Route children>
will be ignored - teamtreehouse - React-router-dom v4 nested routes not working - Question
I'm sorry it looks like I can only post 2 external links.
TL;DR
I've found 2 ways to do the nesting in React Router 4, each one has it's advantages and drawbacks.
First. It's
react-router
's team recommended way, the advantage is that theRoute
components are where they load, but I find it hard to keep track of the routing.Second. Manages somehow to do all the routing on one place, but there is some duplicated code and an unnecessary level of nesting by adding a helper component, also I'm not sure if it's ok to do it this way.
So these are the two ways I found to do the nesting. I'm looking for:
- Any other ways anyone found to do route nesting.
- How should I my nesting? Which way do you think is best?
From this research I've found two ways to do the nesting, I'm working with react-router-dom
.
1. React Router Docs Recommended Way
So according to React Router, doing all your routing on the same file is over, so your nesting now should be done by putting our nested routes inside the component.
import React from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
const Home = () => (
<div>
<h2>Home</h2>
</div>
)
const About = () => (
<div>
<h2>About</h2>
</div>
)
const Topics = () => (
<div>
<Route path="/topics/topic" component={Topic}/>
</div>
)
const Topic = () => (
<div>
<h2>One Topic</h2>
</div>
)
const BasicExample = () => (
<Router>
<div>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</Router>
)
export default BasicExample
2. Putting it all in one place.
Looking around, people have found ways to do all the routing in one file, like on one of the links I refer to, but it has some drawbacks, for example, to use a "Not Found" page you need to user the Switch
component, which is fine, but then if you nest you run into some problems like having to duplicate code. For example, this would work.
2.1 First Level Nesting
const MainLayout = ( {children} ) => (
<div>
<h2>Main Layout</h2>
{children}
</div>
);
const Home = () => (
<div>
<h2>Home</h2>
</div>
);
const About = () => (
<div>
<h2>About</h2>
</div>
);
const FirstLevelNesting = () => (
<Router>
<MainLayout>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route component={NoMatch}/>
</Switch>
</MainLayout>
</div>
</Router>
);
export default FirstLevelNesting;
2.2 Second Level Nesting
Here you can see how to use a helper component to do the nesting on a second level, you can't do the nesting like on the first level, by putting a component like MainLayout
inside the Switch
because when the Switch
reaches it, it will always match the path and we'll never get to NotFound
, that's why we need to use a helper component to do the nesting, then again inside that component we also have to add a NotFound
.
const NestedRoutes = () => (
<div>
<h2>This is my next nest</h2>
<Switch>
<Route exact path='/nextnest' component={Nest}/>
<Route path='/nextnest/about' component={NestAbout}/>
<Route component={NoMatch}/>
</Switch>
</div>
)
const SecondLevelNesting = () => (
<Router>
<MainLayout>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/nextnest" component={NestedRoutes}
<Route component={NoMatch}/>
</Switch>
</MainLayout>
</div>
</Router>
);