Cómo crear una animación de carga en React from Scratch

En este tutorial, veremos cómo crear un cargador giratorio en la biblioteca React de JavaSctript. Aprenderemos cómo crear un cargador usando imágenes GIF y animación CSS desde cero con ejemplos prácticos de código.

Introducción

Cuando se crean aplicaciones React que obtienen contenido de fuentes externas que tardan algún tiempo en cargarse, siempre es una buena idea brindar una experiencia de usuario agradable atrayendo a los usuarios y manteniendo su atención con un cargador, ya que esto ayuda a los usuarios a comprender lo que está sucediendo en lugar de hacerlo. que dejarlos especular.

En esta guía, aprenderemos cómo mostrar la animación del cargador al cargar una aplicación y recuperar contenido de fuentes externas. Usaremos un girador GIF y crearemos un girador desde cero usando CSS.

Con ese fin, crearemos una pequeña aplicación que obtenga cotizaciones, con una pantalla de carga mientras se obtiene una cotización:

react-loading-animation-example

If you'd like to learn more about react-spinners - a library with pre-built spinners, read our "Cómo crear una animación de carga en React con react-spinners"!

Creación de una aplicación React de muestra

Comencemos mirando nuestro marcado React. Básicamente, tenemos dos elementos <div> en el parent <div> (en aras de la simplicidad): uno es el loader-container y el segundo es el main-content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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;

Hasta ahora, solo hemos creado un <div> para nuestro cargador. Ahora, podemos explorar los diversos métodos para obtener un cargador, así como también cómo podemos diseñarlo para que aparezca en un componente, o incluso hacer que aparezca en toda la pantalla.

{.icon aria-hidden=“true”}

Nota: Puedes revisar este repositorio y cotejar el código si es necesario mientras lees esta guía.

Crear una animación de cargador con React - GIF y CSS

Lo primero que debemos hacer antes de implementar una animación de cargador en React es crear la animación en sí. Hay varias formas de hacerlo, pero, en este artículo, veremos dos de ellas: animaciones GIF y animaciones CSS.

Creación de una animación de cargador mediante GIF

Un GIF es una imagen animada que (puede) repetirse infinitamente sin pausa. Se puede hacer con cualquier creador de GIF o desde cero con herramientas de diseño. En esta guía, usaré este GIF y lo haremos aparecer como fondo del loader-container:

1
2
3
4
5
6
7
8
9
.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;
}

{.icon aria-hidden=“true”}

Nota: También puedes aplicar este mismo GIF a otros elementos para localizar el alcance de la animación.

El código anterior nos ayudará a crear un fondo negro que cubrirá toda la pantalla antes de colocar nuestro ícono de carga en el centro. Cuando ejecutamos nuestra aplicación, el loader-container ahora estará en la parte superior porque configuramos el z-index en 1:

¡Excelente! Hemos creado una pantalla de carga utilizando una imagen GIF como cargador. Hay una miríada de otras formas en las que podemos diseñar nuestro loader-container para diferentes efectos. Veamos ahora cómo podríamos crear este cargador con CSS, evitando el uso de imágenes externas, lo que puede suponer una carga en términos de tiempos de carga.

Creación de una animación de cargador mediante CSS

CSS es un lenguaje expresivo que nos permite realizar una variedad de estilos, como dibujar formas, describir el orden relativo de los elementos y sus características, agregar imágenes e incluso animarlas según nuestras necesidades. Hagamos un cargador giratorio muy simple.

¿Recuerdas que teníamos un control giratorio <div> dentro del contenedor en nuestro marcado load-container? Aunque no lo usamos antes, lo usaremos ahora para diseñar el ícono y luego usar load-container para centrar el icono del cargador:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.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);
    }
}

Con CSS, podemos ajustar la forma en que se realiza la animación. ¡Aquí, hemos recreado el GIF de antes! Hasta ahora, hemos discutido dos enfoques principales para crear animaciones de carga. Ahora, echemos un vistazo a cómo podemos ponerlos en acción.

Cómo crear una animación de carga en React

La animación de carga en React difiere de cómo se hace en JavaScript porque ahora usamos los operadores estado y ternario para controlar cuándo aparece y desaparece el cargador. También usaremos el gancho useEffect() para asegurarnos de que aparezca un cargador durante un período de tiempo predeterminado mientras se carga nuestra aplicación. El primer paso es importar ambos ganchos relevantes, seguido de la creación de nuestro estado de carga:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import React, { useState, useEffect } from 'react';

const App = () => {
  const [loading, setLoading] = useState(false);

  return (
       <!-- ... -->
  );
};

export default App;

{.icon aria-hidden=“true”}

Nota: El estado se establece en “falso” de forma predeterminada en el código anterior, y podemos cambiarlo a “verdadero” siempre que queramos que aparezca el “cargador-contenedor”.

Para comenzar, use el método setTimeout() para permitir que el cargador aparezca durante 2 segundos mientras se procesa la página. Este tiempo de espera simula una costosa llamada a la API que tarda en devolver resultados:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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;

Esto significa que cada vez que se procesa nuestra aplicación, nuestro loader-container debe mostrarse durante 2 segundos. Podemos usar un operador ternario para controlar nuestro cargador-contenedor y mostrar la animación en este período de tiempo de espera:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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;

Cuando loading se establece en true, el operador ternario en el código anterior mostrará el loader-container. De lo contrario, mostrará el contenido principal.

If you'd like to read more about ternary operators - read our "Guía del Operador Ternario en JavaScript"!

Implementación de una animación de carga al solicitar contenido de una API

Otro escenario en el que las personas usan una animación de carga en React es cuando cargan contenido desde una fuente externa porque estos datos son externos y su entrega está influenciada por una variedad de eventos externos, además de los tiempos de procesamiento anticipados.

Solicitemos una cotización aleatoria de la API de cotizaciones aleatorias y almacenémoslas en el estado, después de lo cual las mostraremos en la pantalla. Cada vez que enviamos una solicitud, el estado de “carga” se establecerá en “verdadero”. Una vez que se recupera el contenido, lo estableceremos de nuevo en falso, deteniendo la animación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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;

¡Hemos creado un spinner receptivo desde cero! Alternativamente, puede usar la biblioteca react-spinner, que tiene una amplia variedad de animaciones de carga.

If you'd like to learn more about react-spinners - a library with pre-built spinners, read our "Cómo crear una animación de carga en React con react-spinners"!

Conclusión

En esta guía, aprendimos cómo agregar una animación de carga a nuestra aplicación React utilizando dos enfoques diferentes. Importamos un GIF simple y creamos una ruleta desde cero con CSS. Finalmente, hemos analizado cómo integrar la animación en una configuración más realista: obtener datos de una API y mostrar el efecto mientras se espera un resultado.