I\'m learning react and it\'s great, but i\'ve ran into an issue and i\'m not sure what the best practice is to solve it.
I\'m fetching data from an API in my compon
I think the best practice is to tell the user that your data is still loading, then populate the fields with the real data. This approach has been advocated in various blog-posts. Robin Wieruch has a great write up on how to fetch data, with a specific example on how to handle loading data and errors and I will go through his example here. This approach is generally done in two parts.
isLoading
variable. This is a bolean
. We initially set it to false
, because nothing is loading, then set it to true
when we try to fetch the data, and then back to false
once the data is loaded. isLoading
states. Since you did not provide any code, I'll just follow Wieruch's example.
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
dataFromApi: null,
};
}
componentDidMount() {
fetch('https://api.mydomain.com')
.then(response => response.json())
.then(data => this.setState({ dataFromApi: data.dataFromApi }));
}
...
}
export default App;
Here we are using the browser's native fetch() api to get the data when the component mounts via the use of componentDidMount()
. This should be quite similar to what you are doing now. Given that the fetch()
method is asynchronous, the rest of the page will render and the state will be up dated once the data is received.
In order to tell the user that we are waiting for data to load, we simply add isLoading
to our state. so the state becomes:
this.state = {
dataFromApi: null,
isLoading: false,
};
The state for isLoading
is initially false
because we haven't called fetch()
yet. Right before we call fetch()
inside componentDidMount()
we set the state of isLoading
to true, as such:
this.setState({ isLoading: true });
We then need to add a then() method to our fetch()
Promise to set the state of isLoading
to false
, once the data has finished loading.
.then(data => this.setState({ dataFromAPi: data.dataFromApi, isLoading: false }));
The final code looks like this:
class App extends Component {
constructor(props) {
super(props);
this.state = {
dataFromApi: [],
isLoading: false,
};
}
componentDidMount() {
this.setState({ isLoading: true });
fetch('https://api.mydomain.com')
.then(response => response.json())
.then(data => this.setState({ dataFromApi: data.dataFromApi, isLoading: false }));
}
...
}
export default App;
React allows for conditional rendering. We can use a simple if
statement in our render()
method to render the component based on the state of isLoading
.
class App extends Component {
...
render() {
const { hits, isLoading } = this.state;
if (isLoading) {
return Loading ...
;
}
return (
{dataFromApi.map(data =>
-
{data.title}
)}
);
}
}
Hope this helps.