Introduction
When creating React applications that fetch content from external sources that take some time to load, it is always a good idea to provide a pleasant user experience by engaging users and keeping their attention with a loader, as this helps users understand what is going on rather than leaving them to speculate.
In this guide, we will learn how to display loader animation when loading an application and retrieving content from external sources. We'll be using both a GIF spinner and creating a spinner from scratch using CSS.
To that end - we'll build a small application that fetches quotes, with a loading screen while a quote is being fetched:
If you'd like to learn more about
react-spinners
- a library with pre-built spinners, read our "How to Create a Loading Animation in React with react-spinners"!
Creating a Sample React App
Let's begin by looking at our React markup. Basically, we have two <div>
elements in the parent <div>
(for the sake of simplicity) - one is the loader-container
and the second is the main-content
:
import React from 'react';
const App = () => {
return (
<div className="container">
<div className="loader-container">
<div className="spinner"></div>
</div>
<div className="main-content">
<h1>Hello World!</h1>
<p>
This is a demo Project to show how to add animated loading with React.
</p>
<div className="buttons">
<button className="btn">
<a href="#">Read Article</a>
</button>
<button className="btn get-quote">
Generate Quote
</button>
</div>
<div className="quote-section">
<blockquote className="quote">
If you do not express your own original ideas, if you do not listen
to your own being, you will have betrayed yourself.
</blockquote>
- <span className="author">Rollo May</span>
</div>
</div>
</div>
);
};
export default App;
So far, we've only created a <div>
for our loader. Now, we can explore the various methods for obtaining a loader, as well as how we can style it to appear on a component, or even make it appear over the entire screen.
Note: You can check out this repository and cross-check the code if need be while reading this guide.
Create a Loader Animation with React - GIF and CSS
The first thing we must do before implementing a loader animation in React is to create the animation itself. There are several ways we can do that, but, in this article, we'll take a look at two of them - GIF animations and CSS animations.
Creating a Loader Animation Using GIFs
A GIF is an animated image that (can) infinitely repeat itself without pausing. It can be made with any GIF maker or from scratch with design tools. In this guide, we will use this GIF and make it appear as the background of the loader-container
:
.loader-container {
width: 100%;
height: 100vh;
position: fixed;
background: rgba(0, 0, 0, 0.834)
url("https://media.giphy.com/media/8agqybiK5LW8qrG3vJ/giphy.gif") center
no-repeat;
z-index: 1;
}
Note: You can apply this same GIF to other elements as well, to localize the scope of the animation.
The code above will assist us in creating a black background that will cover the entire screen before placing our loader-icon in the center. When we run our application, the loader-container
will now be at the top because we set the z-index
to 1:
Great! We've created a loading screen using a GIF image as the loader. There's a myriad of other ways we can style our loader-container
for different effects. Let's now look at how we could create this loader with CSS, avoiding the use of external images, which can put a burden in terms of loading times.
Creating a Loader Animation Using CSS
CSS is an expressive language that allows us to perform a variety of styling such as drawing shapes, describing relative order of elements and their characteristics, adding images, and even animating them based on our needs. Let's make a very simple spinner loader.
Remember we had a spinner <div>
inside the container in our load-container
markup? Although we didn't use it earlier, we will use it now to style the icon and then use the load-container
to center the loader icon:
.loader-container {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
background: rgba(0, 0, 0, 0.834);
z-index: 1;
}
.spinner {
width: 64px;
height: 64px;
border: 8px solid;
border-color: #3d5af1 transparent #3d5af1 transparent;
border-radius: 50%;
animation: spin-anim 1.2s linear infinite;
}
@keyframes spin-anim {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
With CSS - we can fine-grain tune how the animation is done. Here, we've recreated the GIF from before! So far, we've discussed two major approaches to creating loader animation. Now, let's take a look at how we can put them into action.
How to Create a Loading Animation in React
The loading animation in React differs from how it is done in JavaScript because we now use the state and ternary operators to control when the loader appears and disappears. We will also use the useEffect()
hook to ensure that a loader appears for a predetermined amount of time while our app loads. The first step is to import both relevant hooks, followed by the creation of our loading state:
import React, { useState, useEffect } from 'react';
const App = () => {
const [loading, setLoading] = useState(false);
return (
<!-- ... -->
);
};
export default App;
Note: The state is set to false
by default in the code above, and we can change it to true
whenever we want the loader-container
to appear.
To begin, use the setTimeout()
method to allow the loader to appear for 2 seconds while the page is being rendered. This timeout simulates an expensive API call that takes time to return results:
import React, { useState, useEffect } from 'react';
const App = () => {
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);
return (
<div className="container">
<!-- ... -->
</div>
);
};
export default App;
This means that whenever our app renders, our loader-container
should be displayed for 2 seconds. We can use a ternary operator to control our loader-container
and display the animation in this timeout period:
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
import React, { useState, useEffect } from 'react';
const App = () => {
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);
return (
<div className="container">
{loading ? (
<div className="loader-container">
<div className="spinner"></div>
</div>
) : (
<div className="main-content">
<h1>Hello World!</h1>
<p>
This is a demo Project to show how to add animated loading with
React.
</p>
<div className="buttons">
<button className="btn">
<a href="#">Read Article</a>
</button>
<button className="btn get-quote">
Generate Quote
</button>
</div>
<div className="quote-section">
<blockquote className="quote">{quote.content}</blockquote>-{' '}
<span className="author">{quote.author}</span>
</div>
</div>
)}
</div>
);
};
export default App;
When loading
is set to true
, the ternary operator in the preceding code will display the loader-container
. Otherwise, it will display the main-content
.
If you'd like to read more about ternary operators - read our "Guide to the Ternary Operator in JavaScript"!
Implementing a Loading Animation When Requesting Content From an API
Another scenario in which people use a loading animation in React is when loading content from an external source because this data is external and its delivery is influenced by a variety of external events, besides the anticipated processing times.
Let's request a random quote from the Random Quotes API and store them in the state, after which we'll display them on the screen. Whenever we send a request, the loading
state will be set to true
. Once the content is fetched, we'll set it back to false
, stopping the animation:
import React, { useState, useEffect } from 'react';
const App = () => {
const [loading, setLoading] = useState(false);
const [quote, setQuote] = useState({});
const getRandomQuote = () => {
setLoading(true);
fetch('https://api.quotable.io/random')
.then((res) => res.json())
.then((data) => {
setLoading(false);
setQuote(data);
});
};
return (
<div className="container">
{loading ? (
<div className="loader-container">
<div className="spinner"></div>
</div>
) : (
<div className="main-content">
<h1>Hello World!</h1>
<p>
This is a demo Project to show how to add animated loading with
React.
</p>
<div className="buttons">
<button className="btn">
<a href="#">Read Article</a>
</button>
<button className="btn get-quote" onClick={getRandomQuote}>
Generate Quote
</button>
</div>
<div className="quote-section">
<blockquote className="quote">{quote.content}</blockquote>-{' '}
<span className="author">{quote.author}</span>
</div>
</div>
)}
</div>
);
};
export default App;
We've created a responsive spinner from scratch! Alternatively, you can use the react-spinner
library, which has a wide variety of loader animations.
If you'd like to learn more about
react-spinners
- a library with pre-built spinners, read our "How to Create a Loading Animation in React with react-spinners"!
Conclusion
In this guide, we learned how to add a loading animation to our React application using two different approaches. We've imported a simple GIF and created a spinner from scratch with CSS. Finally, we've taken a look at how to integrate the animation in a more realistic setting - fetching data from an API and displaying the effect while waiting for a result.