Saltar al contenido

Lección 12 de 13 · Lectura y práctica

Limpieza en useEffect

Instala y retira un listener con estado inicial compatible con el servidor; verifica dependencias, desmontaje y Strict Mode.

Del concepto a la práctica

Taller de esta lección

La limpieza debe retirar exactamente el recurso instalado por el efecto. Para un panel que escucha cambios de tamaño, el mismo identificador de función debe usarse al añadir y quitar el listener. De lo contrario, cada montaje puede dejar una suscripción activa y producir actualizaciones después de cerrar el panel.

Ejemplo resuelto

jsx
import {useEffect,useState} from 'react';
function AnchoVentana() {
  const [ancho, setAncho] = useState(0);
  useEffect(() => {
    const actualizar = () => setAncho(window.innerWidth);
    window.addEventListener('resize', actualizar);
    actualizar();
    return () => window.removeEventListener('resize', actualizar);
  }, []);
  return <p>Ancho: {ancho}</p>;
}

El efecto instala una función y la limpieza retira esa misma función.

Pruébalo

  1. Declara el listener dentro del efecto.

  2. Ejecuta una actualización inicial.

  3. Devuelve la llamada de eliminación.

  4. Desmonta el componente y redimensiona la ventana.

Comprueba tu resultado

Mientras está montado, el ancho cambia; después, no debe producir actualizaciones.

Error frecuente: crear otra función al limpiar; corrígelo reutilizando actualizar. El laboratorio es local y autorizado: no conectes listeners ni pruebas a páginas ajenas.

Prueba de suscripción simétrica

Importa useEffect y useState y monta AnchoVentana dentro de un padre que pueda mostrarlo/ocultarlo. Usa herramientas del navegador o un wrapper local de addEventListener/removeEventListener para contar suscripciones de tu componente; no afirmes que la ausencia de mensajes demuestra limpieza. Debe quedar una suscripción resize activa montado y cero al ocultarlo, también después de volver a mostrarlo. Strict Mode puede hacer un ciclo extra de instalación/retirada, pero el saldo final debe seguir siendo uno o cero.

La función de limpieza retira el mismo tipo y referencia, con capture compatible si se configuró. Es distinto de escribir removeEventListener('resize',()=>actualizar()), que crea otra función. El estado inicial0 es estable pero puede mostrar Ancho:0 antes de medir; si quieres evitar esa cifra confusa usa null y Midiendo ventana, como el original. Efectos no se ejecutan durante renderizado de servidor; en Next.js, un archivo que utiliza estos hooks necesita una frontera cliente apropiada. Cambia el tamaño solo mientras está montado y luego tras desmontar, comprobando llamadas al setter y saldo del listener en ambos momentos.

Montar agrega actualizar como listener, limpiar retira esa misma función y un nuevo montaje vuelve a un listener activo; los conteos siguen 0, 1, 0 y 1.
CursaloMapa de práctica
Instalar y retirar el mismo listener

El efecto registra un listener y su limpieza retira la misma función. Tras desmontar quedan cero suscripciones de ese componente; volver a montarlo instala una nueva sin acumular la anterior.

Ver la infografía en tamaño completo ↗

Un efecto instala un recurso y su limpieza lo retira

useEffect sincroniza un componente con un sistema externo. Si instalas un intervalo, un listener o una conexión, devuelve una función que quite ese mismo recurso. React llama a esa limpieza antes de volver a instalar el efecto cuando cambian sus dependencias, y también al desmontar el componente.

Ejemplo original: tamaño de ventana con estado inicial estable

import { useEffect, useState } from "react";

export function WindowSize() {
  const [size, setSize] = useState(null);
  useEffect(() => {
    const handleResize = () => setSize({
      width: window.innerWidth,
      height: window.innerHeight,
    });
    handleResize();
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);
  return <p>{size ? `${size.width} × ${size.height}` : "Midiendo ventana…"}</p>;
}

El render inicial no lee window. Esto permite representar el mismo texto inicial en servidor y cliente. La lectura y el listener se instalan en el efecto, que se ejecuta en el cliente. En Next.js, este componente necesita la directiva "use client" al comienzo del archivo. El código anterior es JavaScript con JSX.

Qué devuelve la limpieza

  • Listener: elimina el mismo tipo de evento y la misma función que registraste.
  • Intervalo: conserva el identificador y llama a clearInterval en la limpieza.
  • Conexión: desconecta la instancia creada por esa ejecución del efecto.
  • Petición pendiente: según la API, cancélala o ignora una respuesta que ya no pertenece a la ejecución vigente.

En desarrollo, Strict Mode puede realizar un ciclo adicional de instalación y limpieza para detectar errores. La limpieza debe dejar el sistema como estaba, sin depender de que el efecto se ejecute una sola vez. No ocultes ese comportamiento quitando el modo de comprobación.

Práctica y revisión

Muestra y oculta WindowSize con un botón en un componente de prueba. Cambia el tamaño de la ventana, oculta el componente y vuelve a mostrarlo. Revisa en las herramientas del navegador que el listener anterior se retiró y que cada montaje deja una sola suscripción activa. Si añades un temporizador, verifica también que deja de actualizar después de desmontar.

Esta es una práctica original para ejecutar en tu proyecto; no afirma una prueba realizada en el navegador del alumno. Referencia: React: useEffect y limpieza.

Sigue con React Fundamentals

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.