Reputation: 11
I'm changing my React application to make use of React.lazy to lazily load components. The current code base makes use of componentDidMount to perform many operations involving child components once a component is mounted. Now that I'm lazily loading components the componentDidMount lifecycle method is being called before the child components have completed loading so the components are not available during execution of componentDidMount. My understanding is that there is a placeholder element rendered to the DOM which is technically 'mounted' which is why the componentDidMount lifecycle method is called. But this causes issues with the logic I currently have in componentDidMount. To make this more concrete, my app code looks something like this:
const SomeOtherComponent = React.lazy(() => import("/path/to/SomeOtherComponent.js"));
class SomeComponent extends Component {
componentDidMount() {
// perform operations on components rendered during render()
}
render() {
<Suspense fallback="<div>Loading...</div>">
<SomeOtherComponent/>
</Suspense>
}
}
The componentDidMount method is called immediately after render(), despite the fact that SomeComponent has not been mounted yet. It seems like componentDidMount should not be called until all of the rendered components are mounted. Am I missing something obvious? Do I need to rewrite major chunks of my code to make use of React.lazy?
Upvotes: 0
Views: 1246
Reputation: 55613
Firstly, your lazy
declaration should be outside the render function.
// move this line outside the render function
const SomeComponent = React.lazy(() => import("/path/to/SomeComponent.js"));
class SomeComponent extends Component {
...
Secondly, lazy
is async
- when componentDidMount
is called, there is a Suspense
component that has rendered and there are no child components (because Suspense
has been thrown a promise and doesn't render it's children until that promise resolves).
componentDidMount() {
// when this method is called, `SomeComponent`
// doesn't exist because `Suspense` doesn't render it's children
// until they are ready
// in short, componentDidMount is called synchronously
// (when the component renders, all components must render synchronously)
// but the tree generated by `SomeComponent` is async (because it's `lazy`)
// and is not available by the time this method is called.
}
render() {
<Suspense fallback="<div>Loading...</div>">
<SomeComponent/>
</Suspense>
}
Upvotes: 0