Saltar al contenido
Curso de React
Todos los cursos Ir al ejercicio →

Datos de internet

  • ⏱ 55 minutos
  • 📶 Nivel: principiante
  • 🧩 Incluye ejercicio

💡 🎯 Al terminar esta lección podrás…

  • Pedir datos con fetch desde un efecto.
  • Mostrar los estados de carga y error.
  • Evitar respuestas obsoletas.
  • Extraer el patrón a un hook reutilizable.

1.La idea: pedir datos desde un efecto

Casi toda aplicación real muestra datos que no están en el código: llegan de un servidor a través de una API. Pedir datos es un efecto secundario (sale de React hacia la red), así que se hace en useEffect, con el patrón de tres estados: cargando, error y datos.

El patrón básico
useEffect(() => {
  async function cargar() {
    try {
      const respuesta = await fetch("https://api.ejemplo.com/usuarios");
      if (!respuesta.ok) throw new Error("Error " + respuesta.status);
      const datos = await respuesta.json();
      setUsuarios(datos);
    } catch (e) {
      setError(e.message);
    } finally {
      setCargando(false);
    }
  }
  cargar();
}, []);

📌 Nota · fetch y async/await

Si necesitas repasar promesas, fetch y async/await, revisa la lección 10 del curso de JavaScript. Aquí las usamos tal cual.

⚠️ Importante · useEffect(async …) no se puede

La función del efecto no puede ser async porque devolvería una promesa, y React espera una función de limpieza (o nada). Por eso se define una función async dentro y se llama al final.

2.Los tres estados de una petición

Una petición pasa por momentos distintos y tu interfaz debe decirle algo útil a la persona en cada uno. Para poder practicar sin depender de internet, estos ejemplos usan una API simulada (pedirUsuarios) que responde tras medio segundo, igual que lo haría una real.

EstadoQué mostrar
CargandoUn indicador: «Cargando…» o un spinner
ErrorUn mensaje claro y, si se puede, un botón para reintentar
ÉxitoLos datos (o un aviso si la lista llegó vacía)
⚛️ Cargando, error y datos
Consola

💡 Consejo · Prueba el error

Cambia pedirUsuarios() por pedirUsuarios(true) y pulsa Ejecutar: verás el camino del error. Probar los tres caminos es parte de construir una pantalla de datos.

3.fetch de verdad

Esta es la petición real, con las comprobaciones importantes. Aquí fetch consulta un pequeño JSON incrustado en la propia dirección (una URL data:), de modo que funciona sin internet, pero el código es idéntico al que usarías con un servidor:

⚛️ fetch, ok y json()
Consola

⚠️ Importante · fetch solo rechaza ante fallos de red

Una respuesta 404 o 500 no lanza error en fetch: tú debes comprobar respuesta.ok (o respuesta.status) y lanzar el error. Sin esa línea, tu interfaz mostraría «éxito» con una página de error.

📌 Nota · CORS y claves

Si la API pertenece a otro dominio, el servidor debe permitir tu origen (CORS). Y nunca pongas claves secretas en el código de React: cualquiera puede verlas en el navegador. Las claves privadas viven en un servidor.

4.Volver a pedir: dependencias y cancelación

Si lo que pides depende de algo (una búsqueda, un id, una página), pon ese valor en las dependencias: el efecto vuelve a ejecutarse cuando cambia. Pero hay un riesgo: si la persona cambia rápido, las respuestas pueden llegar desordenadas. La solución es ignorar las respuestas obsoletas con una bandera en la limpieza:

Ignorar respuestas obsoletas
useEffect(() => {
  let vigente = true;               // «esta petición sigue siendo la actual»

  async function cargar() {
    setCargando(true);
    const datos = await buscar(termino);
    if (vigente) {                  // solo si no llegó otra búsqueda después
      setResultados(datos);
      setCargando(false);
    }
  }
  cargar();

  return () => { vigente = false; };   // limpieza: marca esta petición como vieja
}, [termino]);

Con fetch también puedes cancelar la petición de verdad usando un AbortController y pasando { signal } a fetch; en la limpieza llamas a controlador.abort().

5.Reutilizar: un hook useDatos

El patrón cargando/error/datos se repite en todas las pantallas. Es el candidato perfecto para un hook personalizado:

⚛️ useDatos: cargando, error y datos en un hook
Consola

💡 Consejo · Bibliotecas de datos

En proyectos grandes se usan bibliotecas como TanStack Query o SWR, que ya incluyen caché, reintentos, actualización en segundo plano y cancelación. Entender este patrón manual te permite apreciar lo que hacen por ti.

6.Errores frecuentes

📒 Apuntes para llevar

  • Pedir datos es un efecto: va en useEffect.
  • Maneja siempre tres estados: cargando, error y datos.
  • La función del efecto no es async; define una async dentro y llámala.
  • fetch no rechaza por un 404/500: comprueba res.ok.
  • Si la petición depende de un valor, ponlo en las dependencias e ignora respuestas obsoletas.
  • Extrae el patrón a un hook personalizado (useDatos).
  • En proyectos grandes considera TanStack Query o SWR.
  • Nunca pongas claves secretas en el código del navegador.

7.Glosario

TérminoSignificado
APIServicio al que una aplicación hace peticiones para obtener o enviar datos.
fetchFunción del navegador para hacer peticiones HTTP; devuelve una promesa.
async / awaitSintaxis para escribir código asíncrono como si fuera secuencial.
Estado de cargaIndicador de que la petición sigue en curso.
CORSRegla del navegador que decide qué orígenes pueden leer la respuesta de un servidor.
AbortControllerObjeto que permite cancelar una petición fetch en curso.
TanStack QueryBiblioteca que gestiona datos del servidor: caché, reintentos y sincronización.

🧠 Comprueba lo aprendido

Elige una respuesta en cada pregunta. Verás al instante si acertaste y por qué.

¿Dónde se piden normalmente los datos al montar un componente?

¿Por qué useEffect(async () => …) no es válido?

Una petición devuelve un 404. ¿Qué hace fetch?

¿Cuáles son los tres estados que debes mostrar?

¿Para qué sirve la bandera vigente en la limpieza del efecto?

Tu progreso se guarda en este navegador y se refleja en el índice del curso.

💡 🚀 ¡Ahora te toca!

La práctica fija lo aprendido. Pasa al ejercicio de esta lección.

Ir al ejercicio