useEffect — Efectos secundarios y ciclo de vida
Al finalizar este tema
Comprenderá cuándo se ejecuta useEffect, qué es el array de dependencias y por qué es necesaria la función de limpieza.
¿Qué es un efecto secundario?
La función principal de los componentes de React es recibir el estado y renderizar la interfaz de usuario. Sin embargo, también se requieren otras tareas:
- Obtener datos desde una API
- Configurar temporizadores
- Cambiar el título del documento
- Registrar oyentes de eventos
A estas tareas se las denomina efectos secundarios (side effects). useEffect es el Hook diseñado para gestionar estos efectos secundarios.
Uso básico
import { useEffect, useState } from "react";
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => setUser(data));
}, [userId]);
if (!user) return <p>Loading...</p>;
return <h1>{user.name}</h1>;
}useEffect recibe dos argumentos:
- la función a ejecutar (efecto)
- el array de dependencias (cuándo volver a ejecutarlo)
Array de dependencias
El momento de la ejecución varía según el array de dependencias:
// Se ejecuta en cada renderizado (sin matriz de dependencias)
useEffect(() => {
console.log("Se ejecuta siempre");
});
// Se ejecuta una sola vez al montar (matriz vacía)
useEffect(() => {
console.log("Una sola vez al inicio");
}, []);
// Se ejecuta cada vez que userId cambia
useEffect(() => {
fetchUser(userId);
}, [userId]);React compara si los valores del arreglo de dependencias son diferentes a los del renderizado anterior. Si lo son, vuelve a ejecutar el efecto.
Función de limpieza
useEffect(() => {
const timer = setInterval(() => {
console.log("tick");
}, 1000);
return () => {
clearInterval(timer);
};
}, []);Si una función de efecto devuelve una función, esa es la función de limpieza (cleanup). Se ejecuta en las siguientes situaciones:
- Cuando el componente se desmonta (cuando desaparece de la pantalla)
- Justo antes de que el efecto se vuelva a ejecutar (cuando cambian las dependencias)
Se utiliza para tareas de limpieza como liberar temporizadores, eliminar oyentes de eventos y cancelar suscripciones.
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);Error común: bucle infinito
// ¡Bucle infinito!
useEffect(() => {
setCount(count + 1);
}); // Sin matriz de dependencias → se ejecuta en cada renderizado → setState → re-renderizado → se ejecuta de nuevoAl modificar el estado dentro de un efecto, se produce una nueva renderización; si no hay un array de dependencias, el efecto se ejecuta nuevamente.
// Forma correcta
useEffect(() => {
fetchData().then(setData);
}, []); // Matriz vacía → se ejecuta una sola vezEsencial
useEffectejecuta efectos secundarios después del renderizado. Si el array de dependencias está vacío, se ejecuta una sola vez al montar; si contiene valores, se ejecuta cuando esos valores cambian. Se deben limpiar temporizadores, oyentes y otros recursos mediante la función de limpieza para evitar fugas de memoria.