Skip to content

Create a professional loading Spinner Component in React

Published: at 04:00 PM
Time to read: 10 min
Author: Mouad Nassri

Outline:

  1. Introduction
    • Why you MUST use loading indicators in you apps
    • How using loading indicators improve performance and UX
  2. Live examples in different use cases
  3. Create the spinner component
  4. Explanations
  5. Some use-cases where you can use this loading spinner
  6. Conclusion

1. Introduction

Users usually take few milliseconds to decide whether your website is the one they are looking for or they are in the wrong place, and If you don’t take care of UX, and you don’t give the visitor a quick and clear feedback within your UI, you will loose the attention of your visitors, and your application will be downgraded by search engines.

One of the aspects of a good user experience, is providing loading indicators to your visitors when something is happening behind the scenes in order to encourage the user to stay and understand that he needs to wait for some task to be done. If the user does not see any indicator and the process take a little bit of time, he will leave your website immediately and go to other website to search for the information.

In this article, we will see how to create a highly customizable loading Spinner component, and use it in different use cases like within buttons and loading areas.

2. Live examples within different use cases

A simple spinner:

A spinner inside a button :

A post being loaded:

You can use it whenever and however you want, depending on your needs.

First get spinner SVG

I already have a spinner in form of SVG which maintain its quality when you want to change its size. It has 2 parts, backward part which is a circle fixed (gray), and a quarter circle that should rotate above the backward part (See the following). HERE is a full article to read more about SVG icons and how they boost app performance and user experience.

<svg viewBox="0 0 16 16">
  <circle cx="8" cy="8" r="7" stroke="currentColor" strokeOpacity="0.25" strokeWidth="3" vectorEffect="non-scaling-stroke"></circle>
  <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" strokeWidth="3" strokeLinecap="round" vectorEffect="non-scaling-stroke"></path>
</svg>

3. Create the Spinner component:

Now that we have the spinner SVG, we can create a component and handle every thing that can be configurable like size, color and speed.

const speedValues = {
  slow: "1.2s",
  medium: "0.7s",
  fast: "0.4s",
};

// prettier-ignore
function Spinner({ className = "", size = 26, speed = "medium", color = "black", ...props}) {
  return (
    <svg className={`spinner ${className}`}
      style={{
        animationDuration: speedValues[speed],
        width: size,
        height: size,
      }}
      viewBox="0 0 16 16"
      {...props}
    >
      <circle cx="8" cy="8" r="7" stroke="currentColor" strokeOpacity="0.25" strokeWidth="3" vectorEffect="non-scaling-stroke"></circle>
      <path style={{ color }} d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" strokeWidth="3" strokeLinecap="round" vectorEffect="non-scaling-stroke"></path>
    </svg>
  );
}

export default Spinner;

Add style to your global css file

Before using the Spinner we need create a css file in the same place where you created your component file, and add the following styles in order for animation to work.

.spinner {
  fill: transparent;
  animation: spin 0.8s linear infinite;
  -webkit-animation: spin 0.8s linear infinite;
}

@keyframes spin {
  from {
    transform: none;
  }

  to {
    transform: rotate(360deg);
  }
}

@-webkit-keyframes spin {
  from {
    -webkit-transform: none;
  }

  to {
    -webkit-transform: rotate(360deg);
  }
}

Either add the above styles to your base style file, or import this file directly to your component file.

import './styles.css'

4. Explainations

Styles

Let’s begin with the style first, because it is the engine for our animated spinner.

In the content of our style, we have a spinner class which needs to be given to the svg element within our component, and it has a transparent fill, and it is defined to hide the inner circle and only leave the rotated part and the back part of spinner svg.

We also have a keyframe which is responsible to rotate our spinner, and It has a simple rotation from 0 (transparent: none) to 360 degree, which is used by the spinner animation with a default duration of 800 ms to complete a cycle. The way it is rotating is linear to make animation smooth, and it is infinite until you decide to hide the spinner and show a content or do something right after a long process finish.

Spinner component

Spinner component is a simple React function component that accept several properties to customize the way your spinner will behave. The following is the properties with a simple description:

  className: Classes you may want to pass to the spinner in addition to spinner default class.

  size: Define spinner dimensions; Its value will be passed to the height and width of the spinner element.

  speed: Define the pace of rotation, and It accept 3 possible values, each value has a corresponding time taken to complete a cycle. The less the value, the faster the spinner will rotate;

    fast: takes 400ms to complete one cycle

    medium: takes 700ms to complete one cycle

    slow: takes 1s 200ms to complete one cycle

  color: Define spinner color. (Please notice that only the rotated part will take the color, the back part of the spinner will not take any color, and it is default to gray)

  …props: Other props that you may want to pass to add your custom configs.

5. Some use-cases where you can use this loading spinner

5.1 Search as you type

If your application, contains a search as you type field, you can add this loading spinner in the center of result box while the request is being cooked in order to show the user a feedback that the result is being fetched from the server.

5.2 Infinite scroll

In case you have an infinite scroll and the user reached the end of the result page, you may display a loading spinner centered as a feedback to show your visitors that the incomming result bunch is comming.

5.3 Refresh indicator

If you have a page where data is changed frequently, and the user need to refresh the data from time to time whitout refreshing the page, you may add a small spinner component in the right side of the header, and when the user click on refresh button, display the spinner.

There are a lot of other use cases like when a heavy task is being handled, and your app is connected to the server through a socket channel and a notification is broadcasted, you may display the spinner until the whole process end and more…

I have already showed you some real example at the top like spinner within a button and inside a post container.

6. Conclusion

Showing the user a loading feedback is really important to keep him interested and focused. If your application is doing something heavy and your users do not see any loading or a feedback, they may think that your application does not work properly or something wrong within the app, and they will leave immediately.

Always look for showing feedback to your users, one loading spinner is a perfect choice because it is simple and enough for tyhe user to know that he needs to wait and something is happening. There are some other loading feedbacks which you can also look for like oading shimmer and animated dots and more which we may cover some of them in the next posts.