Zurvin
BLOG

¿Cómo manejo los estados de loading, error y vacío en React?

En una aplicación de React, es común encontrarse con situaciones en las que se necesita manejar el estado de carga, error o vacío de un componente. En este post, vamos a explorar algunas estrategias para manejar estos estados de manera efectiva.

Estado de carga

Situación en la que un componente está esperando que se complete una tarea antes de poder mostrar el contenido. Por ejemplo, si un componente necesita cargar datos de una API antes de mostrar al usuario, es necesario indicar que hay un tiempo de espera antes de mostrar el contenido.

import React, { useState } from 'react';
import useCats from "./useCats";

const MyComponent = () => {
  const { data, isLoading } = useCats();

  if (isLoading) {
    return <div>Cargando...</div>;
  }

  return (
    <div>
      ...
    </div>
  );
}

export default MyComponent;

El componente de ejemplo utiliza el estado isLoading para manejar el estado de carga. Al iniciar la carga de datos, se establece el estado de carga en true. Cuando se completa la tarea, se establece en false. Mientras el estado de carga sea true, se muestra el mensaje "Cargando...". Cuando la tarea está completa, se muestra el contenido de los datos.

La cosa empieza a tener sentido, pero no cantemos victoria. ¿Necesitamos mostrar un loading y ocultar el contenido cada vez que hacemos un llamado al API? ¿Qué pasa si ya tenemos los datos en caché o simplemente queremos volver a llamar en segundo plano para asegurarnos de no contar con data obsoleto?

Nos hace falta indicar a los usuarios cuándo sucede algo en segundo plano. Parece que necesitamos un segundo estado de carga, uno que nos permite seguir mostrando el contenido ya cargado mientras obtenemos otro actualizado.

import React, { useState } from 'react';
import useCats from "./useCats";

const MyComponent = () => {
  const { data, isLoading } = useCats();

  if (isLoading && !data) {
    return <div>Cargando...</div>;
  }

  return (
    <div>
			{isLoading && <div>Progress...</div> }
      ...
    </div>
  );
}

export default MyComponent;

Entonces, sólo cuando aún no hay datos se muestra “Cargando…”, sin embargo cuando contamos con datos existentes de un llamado previo se muestra en mensaje diferente sin ocultar el contenido cargado.

Estado de error

Es una situación en la que se produce un error al realizar una tarea. Por ejemplo, si una solicitud de API falla.

import React, { useState } from 'react';
import useCats from "./useCats";

const MyComponent = () => {
  const { data, isLoading, isError } = useCats();

	if (isError) {
    return <div>Error en carga de datos</div>;
  }

  if (isLoading) {
    return <div>Cargando...</div>;
  }

  return (
    <div>
      ...
    </div>
  );
}

export default MyComponent;

Estado vacío

El estado de “empty state”. El estado que no debe faltar cuando hay ausencia de datos.

import React, { useState } from 'react';
import useCats from "./useCats";

const MyComponent = () => {
  const { data, isLoading, isError } = useCats();

	if (isError) {
    return <div>Error en carga de datos</div>;
  }

  if (isLoading) {
    return <div>Cargando...</div>;
  }

	if (!data) {
    return <div>No hay datos</div>;
  }

  return (
    <div>
      ...
    </div>
  );
}

export default MyComponent;

Nuestro componente ahora funciona perfectamente. Hemos pensado en todo los escenarios.

Tener en cuenta que esto es un ejemplo simplificado basado en un componente simple. En el mundo real es posible que sea necesario crear componentes avanzados para cada estado.