Curso react nivel medio
Introducción
useEffect es un hook en React que permite realizar efectos secundarios en los componentes funcionales. Los efectos secundarios incluyen cosas como:
- Llamadas a APIs.
- Suscripción a eventos.
- Actualización del DOM.
- Limpieza de recursos (como eliminar un
setInterval).
¿Cómo funciona useEffect?
useEffect se ejecuta después de que el componente se renderice. React ejecuta el código dentro de useEffect cada vez que se cumplen las condiciones que definimos.
Ejemplo básico
1import React, { useState, useEffect } from "react"; 2 3function Contador() { 4 const [contador, setContador] = useState(0); 5 6 useEffect(() => { 7 console.log("El componente se renderizó o el contador cambió"); 8 }); 9 10 return ( 11 <div> 12 <p>Has hecho clic {contador} veces</p> 13 <button onClick={() => setContador(contador + 1)}>Incrementar</button> 14 </div> 15 ); 16} 17 18export default Contador;
Explicación
useEffectse ejecuta después de cada render (incluido el inicial).- Cada vez que haces clic en el botón, React renderiza el componente, y el efecto se ejecuta.
Dependencias en useEffect
Podemos controlar cuándo debe ejecutarse useEffect usando el array de dependencias.
Ejemplo: Ejecutar useEffect solo una vez
1useEffect(() => { 2 console.log("El componente se montó"); 3}, []); // <- El array vacío significa que solo se ejecutará al montar el componente
Ejemplo: Ejecutar useEffect cuando cambia una variable
1useEffect(() => { 2 console.log("El contador cambió:", contador); 3}, [contador]); // <- Solo se ejecuta cuando 'contador' cambia
Limpieza en useEffect
Si tu efecto crea algo que necesita limpieza (como un temporizador o una suscripción), debes devolver una función desde el useEffect.
Ejemplo: Temporizador
1function Temporizador() { 2 const [segundos, setSegundos] = useState(0); 3 4 useEffect(() => { 5 const intervalo = setInterval(() => { 6 setSegundos((prev) => prev + 1); 7 }, 1000); 8 9 return () => { 10 clearInterval(intervalo); // Limpiamos el intervalo al desmontar el componente 11 }; 12 }, []); 13 14 return <p>Segundos: {segundos}</p>; 15} 16 17export default Temporizador;
Explicación
setIntervalinicia un temporizador.- La función de limpieza
clearInterval(intervalo)se ejecuta cuando el componente se desmonta o el efecto se vuelve a ejecutar.
Casos Comunes de useEffect
1. Llamadas a una API
1import React, { useState, useEffect } from "react"; 2 3function ListaUsuarios() { 4 const [usuarios, setUsuarios] = useState([]); 5 6 useEffect(() => { 7 fetch("https://jsonplaceholder.typicode.com/users") 8 .then((response) => response.json()) 9 .then((data) => setUsuarios(data)); 10 }, []); // Se ejecuta solo al montar el componente 11 12 return ( 13 <ul> 14 {usuarios.map((usuario) => ( 15 <li key={usuario.id}>{usuario.name}</li> 16 ))} 17 </ul> 18 ); 19} 20 21export default ListaUsuarios;
Explicación
fetchobtiene datos de una API.- Actualizamos el estado con
setUsuariospara mostrar los datos en la pantalla.
2. Suscripción a Eventos
1function Teclado() { 2 const [tecla, setTecla] = useState(""); 3 4 useEffect(() => { 5 const manejarTecla = (e) => setTecla(e.key); 6 7 window.addEventListener("keydown", manejarTecla); 8 9 return () => { 10 window.removeEventListener("keydown", manejarTecla); // Eliminamos el evento 11 }; 12 }, []); 13 14 return <p>Tecla presionada: {tecla}</p>; 15} 16 17export default Teclado;
Explicación
- Nos suscribimos al evento
keydownpara detectar teclas presionadas. - La función de limpieza elimina la suscripción cuando el componente se desmonta.
3. Sincronización con el título del documento
1function Contador() { 2 const [contador, setContador] = useState(0); 3 4 useEffect(() => { 5 document.title = `Clics: ${contador}`; 6 }, [contador]); // Cambia el título solo cuando 'contador' cambia 7 8 return ( 9 <div> 10 <p>Has hecho clic {contador} veces</p> 11 <button onClick={() => setContador(contador + 1)}>Incrementar</button> 12 </div> 13 ); 14} 15 16export default Contador;
Explicación
- Actualizamos el título del documento con cada cambio en el contador.
- El efecto solo se ejecuta cuando
contadorcambia, gracias al array de dependencias.
4. Simular Montar y Desmontar
1function MostrarMensaje() { 2 const [mostrar, setMostrar] = useState(false); 3 4 return ( 5 <div> 6 <button onClick={() => setMostrar(!mostrar)}> 7 {mostrar ? "Ocultar" : "Mostrar"} Mensaje 8 </button> 9 {mostrar && <Mensaje />} 10 </div> 11 ); 12} 13 14function Mensaje() { 15 useEffect(() => { 16 console.log("El componente se montó"); 17 18 return () => { 19 console.log("El componente se desmontó"); 20 }; 21 }, []); 22 23 return <p>¡Hola, mundo!</p>; 24} 25 26export default MostrarMensaje;
Explicación
- Cuando el componente
Mensajese monta, muestra un mensaje en la consola. - Cuando se desmonta (al ocultarlo), ejecuta la limpieza.
Consideraciones Importantes
-
Dependencias Incorrectas
Si omites dependencias necesarias en el array, el efecto puede comportarse de forma inesperada. Usa herramientas como ESLint para detectarlo. -
Efectos en Bucles Infinitos
Si no defines el array de dependencias correctamente, el efecto puede ejecutarse continuamente.1useEffect(() => { 2 setContador(contador + 1); // Esto causará un bucle infinito 3});Solución: Asegúrate de agregar dependencias en el array o usar una función de actualización de estado.
Conclusión
useEffect es un hook poderoso que permite manejar efectos secundarios en React de manera declarativa. Ya sea para sincronizar datos, llamar APIs o manejar eventos, es fundamental entender cómo usarlo correctamente.