Monday, 6 June, 2022 UTC


Summary

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 making it appear over the 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 animated image that (can) infinately 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 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 the 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:
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 these 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.