Reputation: 4527
I have the following React component structure:
<A>
<B>
<C/>
</B>
</A>
I fetch data in component A
. Currently, I put the fetch logic in componentDidMount
. But based on
https://github.com/facebook/react/blob/v15.0.1/docs/docs/ref-03-component-specs.md#mounting-componentdidmount:
The componentDidMount() method of child components is invoked before that of parent components.
So, the fetching only happens after A
, B
, and C
are mounted & rendered
Since in our case, A
has deeply nested components, the fetching needs to wait all those components rendered and mounted.
Is there a way to do fetch earlier?
Upvotes: 4
Views: 160
Reputation: 3407
The componentDidMount() method of child components is invoked before that of parent components.
While you're doing something asynchronous, show a loading spinner or something until all the info is fetched like below:
class App extends Component {
constructor() {
super();
this.state = {
name: 'React',
data: [],
isLoading: true
};
}
componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(data =>
this.setState(() => {
return { data , isLoading: false};
})
);
}
render() {
if (this.state.isLoading) {
return <p>Loading ...</p>; // initially isLoading is true, it renders a loading after fetch components will render
}
return (
<div>
<ul>
{this.state.data.map(data => {
return <li key={data.username}>{data.username} </li>
})}
</ul>
<Hello name={this.state.name}>
<p>
Start editing to see some magic happen :)
</p>
</Hello>
</div>
);
}
}
Upvotes: 1
Reputation: 4527
We managed to improve the performance, up to 2 second faster by following @Julien Bourdic and @Jayavel recommendation in the comment section above:
state = {
isReady: false
}
componentDidMount() {
fetch();
this.setState({ isReady: true });
}
render() {
return this.state.isReady ? <Wrapped {...this.props} /> : null;
}
Basically we render null
when fetching is not finished. This way, component B
and C
won't be mounted & rendered, allowing A
's componentDidMount
(and fetch
) to start earlier.
Upvotes: 1
Reputation: 4436
If you want to keep using React's lifecycle methods, a good option would be to not render the children of this component until componentDidMount is called and your data fetch is out. You could use setState
to manage this.
Alternatively you could look into making data fetches outside of the React lifecycle. This can be a good option depending on what kind of state management solution you use and the general architecture of your app.
Upvotes: 0