I am building a React application, and using React Router for managing routing. The information architecture of the application can be represented as follows:
- App
- Projects
- Project 1
- Objects
- Object 1
- Object 2
- etc...
- Collaborators
- ...
- Services
- Users
The UI of the application would look something like this, when looking at a route such as /#/projects/1/components/1
-----------------------------------------------------------
| | Home > Projects > 0 > Object > 1 |
| Home |--------------------------------------------|
| | |
| Projects | Object 1 |
| | |
| Services | Blah blah blah |
| | |
| Users | |
| | |
-----------------------------------------------------------
Note that for any given route shown in the information architecture scheme above, the view should be rendered in the body section (where 'Component 1' is rendered in the diagram above).
Now I will describe how I have been wrongly implementing this in React using React Router:
I have been using PlainRoutes to define my routes. Here is a short example of how a route is defined:
const routes = [
{
path: '/',
component: App,
name: 'Home',
childRoutes: [
// /projects
{
path: 'projects',
component: Projects,
name: 'Projects'
},
{
path: 'projects/:projectid',
component: ProjectDetails,
name: 'Project Details',
childRoutes: [
{
path: 'objects',
component: Objects,
name: 'Objects'
},
{
path: 'objects/:objectid',
component: ObjectDetails,
name: 'Object Details'
},
{
path: 'collaborators',
component: Collaborators,
name: 'Collaborators'
}
]
},
// /services
{
path: 'services',
component: Services,
name: 'Services'
},
// /users
{
path: 'users',
component: Users,
name: 'Users'
}
]
}
];
which then get fed into the React Router component, like this: <Router routes={routes}></Router>
Doing this sort of worked. When I would attempt to navigate to:
/#/projects
I would see the Projects component rendered in the body of the app.
When I would attempt to navigate to:
/#/projects/1
I would see the ProjectDetail component rendered in the body of the app.
However, when I would attempt to navigate to:
/#/projects/1/objects
I would still see the ProjectDetail component rendered in the body of the app. I am not sure why the router would just stop when the /projects/:projectid
parameter was resolved, and not continue to render components assigned to the /projects/:projectid/objects
route.
I think that the problem was that I was using React Router in the wrong way. Child routes are supposed to be physically nested inside their parent components - not just logically nested. At least, I think that is the problem. Clearly, I am a bit confused as to how React Router is intended to be used - especially the concept of childRoutes
.
The question then is - how to use React Router to give the application the hierarchical structure that I am seeking, as outlined above? I want the router to be aware of the deeply nested structure of the application (for things like breadcrumbs and navigation), but I don't want to physically nest the components inside one another. What are best practices here?
Routes can be nested inside one another, and their paths will nest too (child inheriting the parent).
Now, the last thing you need to do is tell React Router where in the parent Route ( Messages ) should it render the child Route ( Chats ). To do this, you use React Router's Outlet component. If the app's location matches the nested Route 's path , this Outlet component will render the Route 's element .
Considering that you do not want to show both ProjectDetails
and Objects
at the path /#/projects/1/objects
, then you do not want to nest these routes.
childRoutes: [
// /projects
{
path: 'projects',
component: Projects,
name: 'Projects'
},
{
path: 'projects/:projectid',
component: ProjectDetails,
name: 'Project Details',
},
{
path: 'projects/:projectid/objects',
component: Objects,
name: 'Objects'
},
{
path: 'projects/:projectid/objects/:objectid',
component: ObjectDetails,
name: 'Object Details'
},
You would nest routes only if you were intending Objects
to be populated inside this.props.children
of ProjectDetails
.
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