Make a state for loading, set it to true, and then show a loading element if the state is set to true. When your API loads, change the loading state to false.
class App extends React.Component {
state = {
loading: true
};
api() {
// axios API call here
// ideally you would callback
// but for simple terms:
this.setState({
loading: false
});
}
componentDidMount() {
setTimeout(() => this.setState({ loading: false }), 1500); // simulates an async action, and hides the spinner
}
render() {
const { loading } = this.state;
if(loading) { // if your component doesn't have to wait for an async action, remove this block
return null; // render null when app is not ready
}
return (
<div>I'm the app</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
Or you could make the loader using the CSS :empty pseudo class to show a loader when the list is empty (before your API fills it):
.loader:empty {
position: absolute;
top: calc(50% - 4em);
left: calc(50% - 4em);
width: 6em;
height: 6em;
border: 1.1em solid rgba(0, 0, 0, 0.2);
border-left: 1.1em solid #000000;
border-radius: 50%;
animation: load8 1.1s infinite linear;
}
@keyframes load8 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
Or you can use both techniques to ensure the loader always shows, and there's no JS-like FOUC. Shoutout to Ori on StackOverflow for the snippets.