CodeForge

React 19 de Cero a Experto / Efectos y ciclo de vida

useEffect: sincronizar con el mundo exterior

Teoría22 min20 XP

Hasta ahora tu componente vivía en una burbuja: recibía props, guardaba estado, devolvía UI. Puro y feliz. Pero las apps reales tienen que hablar con el MUNDO EXTERIOR —el título de la pestaña, un temporizador, el localStorage, una API—. Eso NO es renderizar: es un EFECTO SECUNDARIO. Y React tiene un hook para eso, con reglas precisas: useEffect. Hoy entiendes qué es un efecto, cuándo corre y por qué el 90% de los bugs de React viven aquí.

Renderizar vs tocar el mundo

El primer efecto

useEffect recibe una función (el efecto) y corre DESPUÉS de que React pinta la pantalla. Aquí sincronizamos algo externo —el título de la pestaña del navegador— con nuestro estado:

Cada vez que haces clic, cambia cuenta, React re-renderiza, y DESPUÉS del render corre el efecto: actualiza document.title. Cambiar el título del documento no es "describir UI" —es tocar el mundo del navegador—, por eso va en un efecto y no directo en el return. Poner document.title = ... en el cuerpo del componente sería ensuciar el render; en un efecto, React lo ejecuta en el momento seguro.

El array de dependencias

Cuándo NO va en el body

Un error de principiante es tocar el mundo directo en el cuerpo del componente:

body-vs-efecto.tsx
export default function App() {
const [cuenta, setCuenta] = useState(0);

// ❌ MAL: tocar el mundo exterior en el cuerpo del render.
// Corre en cada render, puede correr durante el cálculo de la UI y romper cosas.
document.title = `Clics: ${cuenta}`;

// ✅ BIEN: dentro de useEffect, que React corre DESPUÉS de pintar, de forma segura.
useEffect(() => {
  document.title = `Clics: ${cuenta}`;
}, [cuenta]);

return <button onClick={() => setCuenta(cuenta + 1)}>+</button>;
}

El cuerpo del componente debe ser PURO: calcular y devolver UI, nada más (¿recuerdas las funciones puras del SC-02?). Todo lo que sea un efecto secundario —tocar el DOM directo, arrancar timers, llamar APIs— va en useEffect. React se reserva el derecho de ejecutar el cuerpo varias veces o en momentos raros; solo los efectos tienen la garantía de correr después de un render real.

¿Cuándo se ejecuta un useEffect(fn, [x]) y qué significa ese [x]?

Mini-reto

Sincroniza el mundo con el estado: 1) crea un estado online (booleano) y un botón que lo alterna; 2) en un useEffect que dependa de online, cambia document.title a "● En línea" o "○ Desconectado" según el valor (fíjate en la pestaña); 3) agrega un console.log dentro del efecto y observa en qué momento aparece respecto al render. Confirma que el efecto corre DESPUÉS de pintar y solo cuando online cambia.

Qué sigue

Ya disparas efectos. Pero muchos efectos abren algo que hay que CERRAR: un setInterval que hay que limpiar, una suscripción que hay que cancelar. Si no lo haces, se acumulan fugas. La próxima lección trae la función de limpieza (cleanup) y el ciclo de vida completo de un efecto: montar, actualizar, desmontar.