useEffect
El hook useEffect
en React es uno de los más utilizados y poderosos. Permite a los componentes funcionales ejecutar efectos secundarios en respuesta a cambios en el estado, las propiedades o al montar/desmontar el componente.
¿Qué es un efecto secundario?
Un efecto secundario es cualquier operación que interactúa con el “mundo externo” o cambia algo fuera del ciclo de renderizado puro de React, como:
- Llamadas a APIs o solicitudes HTTP.
- Manipulación del DOM directamente.
- Configuración de temporizadores (e.g.,
setInterval
,setTimeout
). - Suscripciones a eventos.
Estructura de useEffect
El hook useEffect
se define así:
useEffect(() => {
// Código del efecto secundario.
return () => {
// Código opcional de limpieza.
};
}, [dependencias]);
- Callback principal: Es una función que contiene el efecto secundario a ejecutar.
- Función de limpieza (opcional): Sirve para limpiar recursos (e.g., eliminar temporizadores, desuscribirse de eventos).
- Dependencias (opcional): Es un array de variables que el efecto “escucha”. Cuando estas cambian, el efecto se vuelve a ejecutar. Si está vacío (
[]
), el efecto se ejecuta una sola vez al montar el componente.
Ejemplo 1: Ejecutar un efecto al montar el componente
import React, { useEffect } from "react";
function App() {
useEffect(() => {
console.log("Componente montado");
return () => {
console.log("Componente desmontado");
};
}, []); // Dependencias vacías
return <h1>Hola, mundo</h1>;
}
export default App;
Explicación:
- El
console.log
se ejecuta una vez cuando el componente se monta. - La función de limpieza (return) se ejecuta cuando el componente se desmonta.
Ejemplo 2: Efecto dependiente de una variable
import React, { useState, useEffect } from "react";
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`El contador cambió a: ${count}`);
}, [count]); // Se ejecuta cuando `count` cambia.
return (
<div>
<p>Has hecho clic {count} veces</p>
<button onClick={() => setCount(count + 1)}>Incrementar</button>
</div>
);
}
export default Counter;
Explicación:
- Cada vez que el estado
count
cambia, el efecto se ejecuta. - Si
count
no cambia, el efecto no se ejecuta nuevamente.
Ejemplo 3: Llamada a una API
import React, { useState, useEffect } from "react";
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json())
.then((json) => setData(json));
return () => {
console.log("Limpieza de efecto (si aplica)");
};
}, []); // Solo se ejecuta una vez, al montar el componente.
return (
<div>
{data ? <p>{data.title}</p> : <p>Cargando datos...</p>}
</div>
);
}
export default DataFetcher;
Explicación:
- La solicitud
fetch
se realiza al montar el componente. - La limpieza sería útil en efectos como suscripciones o temporizadores, pero no es necesaria aquí.
Ejemplo 4: Temporizadores con limpieza
import React, { useState, useEffect } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => {
clearInterval(interval); // Limpieza del temporizador al desmontar.
};
}, []); // Solo al montar/desmontar.
return <p>Segundos: {seconds}</p>;
}
export default Timer;
Explicación:
- Un temporizador se inicia al montar el componente.
- La función de limpieza detiene el temporizador al desmontar el componente para evitar fugas de memoria.
Consideraciones importantes
- Orden de ejecución:
- Primero se ejecuta la limpieza del efecto anterior (si existe).
- Luego se ejecuta el nuevo efecto.
- Dependencias omitidas:
- Si no incluyes el array de dependencias, el efecto se ejecutará en cada renderizado, lo que puede causar problemas de rendimiento o comportamientos inesperados.
- Ejemplo de mal uso:
useEffect(() => { // Esto podría crear un bucle infinito si `count` cambia constantemente. setCount(count + 1); });
- Reglas de los hooks:
- Solo llama
useEffect
en el nivel superior de tu componente. - No lo uses dentro de bucles, condiciones o funciones anidadas.
- Solo llama
Resumen
El useEffect
permite manejar efectos secundarios en componentes funcionales de manera eficiente. Entender cómo funcionan las dependencias y la limpieza es clave para evitar errores comunes como bucles infinitos o fugas de memoria.