El hook useEffect
es uno de los hooks más importantes y utilizados en React. Permite realizar efectos secundarios en componentes funcionales, como la manipulación del DOM, la suscripción a eventos, la recuperación de datos, entre otros. En este tema, aprenderemos cómo y cuándo usar useEffect
, así como algunos patrones comunes y mejores prácticas.
Conceptos Clave
- Efectos Secundarios: Operaciones que afectan algo fuera del alcance de la función que las ejecuta, como la manipulación del DOM o la llamada a una API.
- Dependencias: Variables que, cuando cambian, desencadenan la ejecución del efecto.
- Limpieza de Efectos: Funciones que se ejecutan para limpiar o cancelar efectos anteriores antes de ejecutar un nuevo efecto.
Sintaxis Básica
import React, { useEffect } from 'react'; function MiComponente() { useEffect(() => { // Código del efecto console.log('El componente se ha montado o actualizado'); // Función de limpieza return () => { console.log('El componente se va a desmontar o actualizar'); }; }, []); // Array de dependencias return <div>Hola, Mundo!</div>; }
Explicación del Código
- Importación: Importamos
useEffect
desde React. - Definición del Efecto:
useEffect
toma una función que contiene el código del efecto. - Función de Limpieza: La función de limpieza se devuelve desde la función del efecto y se ejecuta antes de que el componente se desmonte o antes de ejecutar el efecto nuevamente.
- Array de Dependencias: El segundo argumento de
useEffect
es un array de dependencias. Si está vacío, el efecto solo se ejecuta una vez, después del primer renderizado.
Ejemplo Práctico: Llamada a una API
Vamos a crear un componente que haga una llamada a una API cuando se monte y muestre los datos obtenidos.
import React, { useState, useEffect } from 'react'; function DatosUsuario() { const [usuario, setUsuario] = useState(null); useEffect(() => { // Llamada a la API fetch('https://jsonplaceholder.typicode.com/users/1') .then(response => response.json()) .then(data => setUsuario(data)) .catch(error => console.error('Error al obtener los datos:', error)); }, []); // El efecto se ejecuta solo una vez if (!usuario) { return <div>Cargando...</div>; } return ( <div> <h1>{usuario.name}</h1> <p>Email: {usuario.email}</p> <p>Teléfono: {usuario.phone}</p> </div> ); } export default DatosUsuario;
Explicación del Código
- Estado Inicial: Usamos
useState
para manejar el estado del usuario. - Llamada a la API: Dentro de
useEffect
, hacemos una llamada a la API para obtener los datos del usuario. - Actualización del Estado: Cuando los datos se obtienen correctamente, actualizamos el estado con
setUsuario
. - Renderizado Condicional: Mientras los datos se están cargando, mostramos un mensaje de "Cargando...".
Ejercicio Práctico
Ejercicio
Crea un componente que haga una llamada a una API para obtener una lista de publicaciones y las muestre en pantalla. Asegúrate de manejar el estado de carga y los posibles errores.
Solución
import React, { useState, useEffect } from 'react'; function ListaPublicaciones() { const [publicaciones, setPublicaciones] = useState([]); const [cargando, setCargando] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch('https://jsonplaceholder.typicode.com/posts') .then(response => response.json()) .then(data => { setPublicaciones(data); setCargando(false); }) .catch(error => { setError(error); setCargando(false); }); }, []); if (cargando) { return <div>Cargando...</div>; } if (error) { return <div>Error: {error.message}</div>; } return ( <div> <h1>Lista de Publicaciones</h1> <ul> {publicaciones.map(publicacion => ( <li key={publicacion.id}>{publicacion.title}</li> ))} </ul> </div> ); } export default ListaPublicaciones;
Explicación del Código
- Estado Inicial: Usamos
useState
para manejar el estado de las publicaciones, el estado de carga y los posibles errores. - Llamada a la API: Dentro de
useEffect
, hacemos una llamada a la API para obtener las publicaciones. - Actualización del Estado: Actualizamos el estado con los datos obtenidos o con el error en caso de fallo.
- Renderizado Condicional: Mostramos un mensaje de "Cargando..." mientras se obtienen los datos y un mensaje de error si ocurre algún problema.
Resumen
En esta lección, hemos aprendido a usar el hook useEffect
para manejar efectos secundarios en componentes funcionales de React. Hemos visto cómo hacer llamadas a APIs, manejar el estado de carga y errores, y cómo limpiar efectos cuando sea necesario. Con esta base, estarás preparado para manejar efectos secundarios en tus aplicaciones React de manera eficiente y efectiva.
Curso de React
Módulo 1: Introducción a React
- ¿Qué es React?
- Configuración del Entorno de Desarrollo
- Hola Mundo en React
- JSX: Extensión de Sintaxis de JavaScript
Módulo 2: Componentes de React
- Entendiendo los Componentes
- Componentes Funcionales vs de Clase
- Props: Pasando Datos a Componentes
- State: Gestión del Estado del Componente
Módulo 3: Trabajando con Eventos
- Manejo de Eventos en React
- Renderizado Condicional
- Listas y Claves
- Formularios y Componentes Controlados
Módulo 4: Conceptos Avanzados de Componentes
- Elevando el Estado
- Composición vs Herencia
- Métodos del Ciclo de Vida de React
- Hooks: Introducción y Uso Básico
Módulo 5: Hooks de React
Módulo 6: Enrutamiento en React
Módulo 7: Gestión del Estado
- Introducción a la Gestión del Estado
- API de Contexto
- Redux: Introducción y Configuración
- Redux: Acciones y Reductores
- Redux: Conectando a React
Módulo 8: Optimización del Rendimiento
- Técnicas de Optimización del Rendimiento en React
- Memorización con React.memo
- Hooks useMemo y useCallback
- División de Código y Carga Perezosa
Módulo 9: Pruebas en React
- Introducción a las Pruebas
- Pruebas Unitarias con Jest
- Pruebas de Componentes con React Testing Library
- Pruebas de Extremo a Extremo con Cypress
Módulo 10: Temas Avanzados
- Renderizado del Lado del Servidor (SSR) con Next.js
- Generación de Sitios Estáticos (SSG) con Next.js
- TypeScript con React
- React Native: Creación de Aplicaciones Móviles