No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de React.js

Curso de React.js

Juan David Castro Gallego

Juan David Castro Gallego

Estados de carga y error

19/34
Recursos

¿Cómo implementar estados de carga y error en una aplicación React usando hooks?

En las aplicaciones web actuales, los estados de carga y error son vitales para mejorar la experiencia del usuario, pues permiten informar al usuario sobre lo que ocurre en segundo plano. En este artículo, exploraremos cómo implementar estos estados de forma efectiva en una aplicación React utilizando un Custom Hook.

¿Cómo simular un retraso en el almacenamiento local?

Simular un retraso en la obtención de datos de localStorage nos ayuda a comprender cómo manejar datos asincrónicos en nuestra aplicación. Aunque localStorage suele ser rápido y síncrono, es relevante aprender a gestionar posibles demoras. Para lograr esto:

  1. Usamos setTimeout para encapsular llamadas dentro de un retardo predefinido (por ejemplo, dos o tres segundos).
  2. Devolvemos los datos simulando que provienen de una fuente asincrónica.
const useLocalStorage = (key, initialValue) => {
  const [storedValue, setStoredValue] = React.useState(initialValue);

  React.useEffect(() => {
    const retrieveData = async () => {
      await new Promise(resolve => setTimeout(resolve, 2000));
      const item = window.localStorage.getItem(key);
      item ? setStoredValue(JSON.parse(item)) : setStoredValue(initialValue);
    };
    retrieveData();
  }, [initialValue, key]);

  return [storedValue, setStoredValue];
};

¿Cómo manejar estados de carga y error?

Para mantener a los usuarios informados sobre la carga y posibles errores:

  1. Creamos dos estados mediante el hook useState: loading y error.
  2. loading inicializa a true y cambia a false cuando los datos han sido cargados.
  3. error se inicializa en false, cambiando a true en caso de ocurrir un error.
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(false);

React.useEffect(() => {
  async function fetchData() {
    try {
      // Simular retraso
      await new Promise((resolve) => setTimeout(resolve, 2000));
      const item = window.localStorage.getItem(key);
      // Manejar datos
      item ? setStoredValue(JSON.parse(item)) : setStoredValue(initialValue);
    } catch (err) {
      setError(true);
    } finally {
      setLoading(false);
    }
  }
  fetchData();
}, [key, initialValue]);

¿Cómo mostrarlos en la interfaz?

Finalmente, mostramos mensajes adecuados según el estado:

  • Cargando: Mostramos un mensaje simple como "Estamos cargando..."
  • Error: Usamos un mensaje llamativo para indicar problemas, como "¡Hubo un error!"
  • Sin elementos: Cuando el array está vacío, indicamos al usuario que puede empezar a añadir elementos.
return (
  <div>
    {loading && <p>Estamos cargando...</p>}
    {error && <p>¡Hubo un error!</p>}
    {!loading && !error && storedValue.length === 0 && <p>Crea tu primer todo</p>}
    {!loading && !error && storedValue.map(todo => <Item key={todo.id} {...todo} />)}
  </div>
);

Recomendaciones finales

Cuando trabajamos con Custom Hooks que retornan múltiples valores, seguir las siguientes prácticas mejora la claridad de nuestro código:

  • Retornar los valores dentro de un objeto en vez de un array para clarificar el significado de cada valor.
  • Usar destructuración nombrada en el componente que consume el hook.
const { item, loading, error } = useLocalStorage('todos', []);

Este enfoque garantiza que nuestros componentes sean mantenibles y entendibles a largo plazo. ¡Sigue explorando y aplicando estas técnicas para optimizar la UX en tus aplicaciones React!

Aportes 12

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Dato curioso platzi esta hecho con react

Por fin ya entendí como grabaron el curso

El VSC realmente solo es el 70% de la pantalla el 30% demás es agregado en edición al igual que sus elementos y lineas para que coincida, gran trabajo pero por unos pixeles y los símbolos duplicados me di de cuenta sin embargo es un gran avance

Otra forma de realizar la logica para informarle a el usuario que debe crear un TODO es

!loading && !searchedTodos.length && 'Crea algún TODO'}

si es 0 es un valor Falsy y al negarlo se convierte en verdadero
https://developer.mozilla.org/en-US/docs/Glossary/Falsy

Dato curioso, de la siguiente manera se pueden importar las diferentes herramientas que nos provee React:

import React, { useState, useEffect } from "react";

quiero dar mi aporte dejo mi codigo aqui para que puedan entender el flujo de la app que explica el profe

import React from "react";
import { useEffect } from "react";
//custom Hooks
export const useLocalStorage = (itemName, initialValue)=>{
    //local storage
    const item_Todos = () => {
        /**
         * Retrieves the value of an item from the local storage. If the item does not exist, it sets the initial value for the item in the local storage and returns the initial value. If the item exists, it returns the value of the item from the local storage.
         * 
         * @returns {any} The value of the item from the local storage.
         */
        let localStorageItem = JSON.parse(localStorage.getItem(itemName));
        if (!localStorageItem) {
            localStorage.setItem(itemName, JSON.stringify(initialValue));
            return (localStorageItem = initialValue);
        } else {
            return localStorageItem;
        }
    };
    //state of react
    const [item, setItem] = React.useState(initialValue);
    const [loading, setLoading] = React.useState(true);
    const [error, setError] = React.useState(false);
    //useEffect
    useEffect(()=>{
        setTimeout(()=>{
            try {
                setItem(item_Todos());
                setLoading(false);
            } catch (error) {
                setLoading(false);
                setError(true);
            }
        }, 1800);
    },[])

    //almacenamiento en local storage
    const saveItem=(newItem)=>{
        localStorage.setItem(itemName, JSON.stringify(newItem));
        setItem(newItem);
    }
    return {item, saveItem, loading, error}
}
 
No sabia que se podia cambiar el nombre de las propiedade de un objeto al ser recibidas
Yo realice los pasos de esta clase y no me salieron los errores. que alegría. lo único es que nunca cargaron los Todos. salía el mensaje de cargar por tiempo infinito jeje. ![](https://static.platzi.com/media/user_upload/image-17c2156e-30e2-4988-aba1-ef9bd6d8363b.jpg)
Profe buenos días La verdad no sabe explicar, con todo respeto enfóquese en como hacer que el alumno entienda lo que usted esta tratando de enseñar, habla y dice palabras para usted mismo y usted mismo se las termina contestando, deje de palabrear
En mi opinion esta logica es muy compleja. Yo creo que lo mejor en este caso crear un estado del status del fetch y tener una sola fuente de verdad. Por ejemplo ```jsx const \[status, setStatus] = useState({ value: 'loading', message: null }); useEffect(() => { fetch(url). .then(response => response.json()) .then(data => {setStatus({ value: 'success', message: data.message })}) .catch(error => {setStatus({ value: 'error', message: error.message })}); }, \[]); ``` Al final solo checamos ese estado ```jsx {status.value === 'loading' && "Loading..."} {status.value === 'error' && "Error"} {status.value === 'success' && data} ```
Hola! quiero compartir con ustedes un proyecto propio de un restaurante realizado a partir de este curso... todas las observaciones son bienvenidas gracias link deploy <https://alejog1996.github.io/Dtravesia_menuPage/> link repositorio <https://github.com/AlejoG1996/Dtravesia_menuPage>
Solucion, aplique validaciones y el uso de useMemo para que esa lógica solo se ejecute en caso que las variables cambien ![](https://static.platzi.com/media/user_upload/image-89958b86-11db-41b4-9131-368b9157147b.jpg)![](https://static.platzi.com/media/user_upload/image-c4560341-bf67-428a-9f2f-d429ee52b355.jpg)