I have a nested route like this:
<Route path="modules" ponent={Modules}>
<Route path=":moduleId" ponent={Module}/>
</Route>
I noticed that Module is mounting before Modules mounts. Is this the intended functionality of nested routes? I ask because I have some data gathering happening in Modules that needs to be resolved in order for Module to render as intended.
How is this possible if I can see that Modules has rendered before it even mounts?
I have a nested route like this:
<Route path="modules" ponent={Modules}>
<Route path=":moduleId" ponent={Module}/>
</Route>
I noticed that Module is mounting before Modules mounts. Is this the intended functionality of nested routes? I ask because I have some data gathering happening in Modules that needs to be resolved in order for Module to render as intended.
How is this possible if I can see that Modules has rendered before it even mounts?
Share Improve this question edited Dec 8, 2016 at 17:12 connected_user asked Dec 8, 2016 at 17:09 connected_userconnected_user 9362 gold badges10 silver badges28 bronze badges 1- Yes, it should go like this. – Piotr Sołtysiak Commented Dec 8, 2016 at 17:12
2 Answers
Reset to default 5This is not specific to react-router
. In the React Component
life-cycle:
Children are mounted before their parents.
ponentWillMount
runs child-first.Parents are unmounted before their children.
ponentWillUnmount
runs parent-first.
Think about it this way: if you're constructing something, first you attach the smaller parts to the larger parts, progressively, until you have the plete thing. If you're dismantling it, first you remove the larger pieces, and then disassemble each of those pieces, until you're back to the ponents.
What you are seeing is because react-router
doesn't really use the React lifecycle process to render its children.
Instead, react-router
individually renders each <Route>
's ponent and then merges them together. This is why you have to include this.props.children
in a ponent route that has child routes. You can see the code responsible for this in the <RouterContext>
's render function.
Essentially what it does is that it takes the most nested route ponent and renders it. Then, it takes the next most nested ponent and renders that with the previously rendered ponent as its children
prop. This continues down the line until you reach the root route ponent.
Given the routes:
<Route path="/" ponent={App}>
<Route path="inbox" ponent={Inbox}>
<Route path="messages/:id" ponent={Message} />
</Route>
</Route>
When you visit /inbox/messages/12
, react-router
will do the following:
- Render
<Message routeParams={{ id: 12 }} />
and store result aselement
. - Render
<Inbox children={element} />
and store result aselement
. - Render
<App children={element} />
and return result.