Hooks en react: Extendiendo la lógica de los componentes.
Como hemos comentado en el post sobre los estados, los hooks han revolucionado la forma en que manejamos el estado y la lógica en componentes funcionales, permitiendo que nuestro código sea más legible y mantenible. Expliquemos ahora los hooks y cómo se relacionan con los estados en React.
Relación Entre los Hooks y los Estados
Los hooks y los estados están intrínsecamente relacionados en React. Los hooks son funciones especiales que permiten a los componentes funcionales acceder y gestionar estados, entre otras funcionalidades. Uno de los hooks más utilizados para el manejo de estados es useState (visto anteriormente).
UseState nos permite declarar y gestionar estados en componentes funcionales, y a través de ello, podemos tener un estado local en nuestro componente funcional y actualizarlo de manera segura. Esta relación permite que los componentes funcionales tengan el mismo poder de manejo de estados que los componentes de clase, pero con una sintaxis más limpia y concisa.
Al igual que cuando tratamos el tema de los estados, consideramos los hooks otro de los grandes pilares de la programación de react.
Ejemplo de Uso de Hooks
Veamos un ejemplo simple de cómo usar el hook useState para agregar un contador a un componente funcional:
import React, { useState } from 'react';
function ListaDeTareas() {
const [tareas, setTareas] = useState([]);
const [nuevaTarea, setNuevaTarea] = useState('');
const agregarTarea = () => {
if (nuevaTarea.trim() !== '') {
setTareas([...tareas, nuevaTarea]);
setNuevaTarea('');
}
};
return (
<div>
<h1>Lista de Tareas</h1>
<input
type="text"
placeholder="Nueva Tarea"
value={nuevaTarea}
onChange={(e) => setNuevaTarea(e.target.value)}
/>
<button onClick={agregarTarea}>Agregar</button>
<ul>
{tareas.map((tarea, index) => (
<li key={index}>{tarea}</li>
))}
</ul>
</div>
);
}
export default ListaDeTareas;
Si has visto el post en el que realizamos una aplicación de tareas sencilla, seguro que la estructura de este código te suena, de lo contrario puedes verlo aquí.
En este ejemplo:
- Utilizamos el hook useState para declarar dos estados: tareas y nuevaTarea. tareas es un arreglo que almacena las tareas existentes, y nuevaTarea es una cadena que almacena la tarea que el usuario está ingresando.
- En la función agregarTarea, verificamos si la cadena nuevaTarea no está vacía antes de agregarla al arreglo de tareas.
- El input de texto permite al usuario ingresar una nueva tarea y actualiza el estado de nuevaTarea cuando se produce un cambio en el input.
- Cuando el usuario hace clic en el botón «Agregar», llamamos a la función agregarTarea para agregar la nueva tarea al arreglo tareas y luego limpiamos el input.
- Renderizamos la lista de tareas existentes utilizando map para iterar sobre el arreglo tareas y mostrar cada tarea como un elemento de la lista.
Más hooks, uso de useEffect
Desde luego, useState es solo uno de los muchos hooks existentes en react, de los cuales, cada uno aporta funcionalidades específicas, para exponer esta peculiaridades trataremos también de manera breve el uso de useEffect, el cual se utiliza para crear efectos secundarios al flujo sobre los componentes, esto es posible debido a que se ejecutan después del renderizado.
Un ejemplo:
import React, { useState, useEffect } from 'react';
function EjemploUseEffect() {
const [contador, setContador] = useState(0);
// useEffect se ejecutará después de cada renderizado del componente
useEffect(() => {
// Este código se ejecuta después del renderizado inicial y de cada actualización
document.title = `Contador: ${contador}`;
// Puedes realizar efectos secundarios aquí, como peticiones a una API
// o manipulación del DOM
// No olvides limpiar los efectos si es necesario (ve más abajo)
return () => {
// Este código se ejecuta antes de que se realice un nuevo renderizado
// Aquí puedes realizar limpieza de recursos si es necesario
};
}, [contador]); // El array de dependencias determina cuándo se ejecuta useEffect
const incrementar = () => {
setContador(contador + 1);
};
return (
<div>
<h1>Contador: {contador}</h1>
<button onClick={incrementar}>Incrementar</button>
</div>
);
}
export default EjemploUseEffect;
En este ejemplo:
Creamos un componente funcional llamado «EjemploUseEffect» que utiliza el hook «useState» para mantener un estado llamado «contador» y un botón que permite incrementar ese contador.
Luego, utilizamos el hook «useEffect» para realizar un efecto secundario. En este caso, actualizamos el título del documento (la pestaña del navegador) para reflejar el valor del contador. Esto se hace dentro de la función de efecto que proporcionamos a «useEffect».
El segundo argumento de «useEffect» es un array de dependencias, que determina cuándo se ejecuta el efecto. En este caso, hemos especificado «[contador]», lo que significa que el efecto se ejecutará cada vez que «contador» cambie de valor. Esto garantiza que el título del documento se actualice cuando cambia el valor del contador.
Además, dentro de la función de efecto, puedes realizar otras tareas, como realizar solicitudes a una API o manipular el DOM. Si necesitas limpiar recursos o realizar acciones antes de que se realice un nuevo renderizado, puedes hacerlo dentro de la función de limpieza que devuelve «useEffect».
El funcionamiento de este código obedece a una suscripción a eventos, un concepto muy interesante, pero más complejo, en el que profundizaremos en otro post.
Resumen
Antes de nada, dado que tratamos la diferencia entre los componentes funcionales y de clase, es interesante comentar que los hooks y por tanto los componentes funcionales se añadieron en la versión de React 16.8, por tanto, si trabajas con versiones anteriores probablemente debas utilizar componentes de clase.
Y resumiendo un poco, hemos visto hasta ahora la creación de pequeñas aplicaciones básicas usando react, introducido el uso de estados y el control de los mismos a través de los hooks más generales, con lo visto hasta ahora ya podemos hablar de dinamismo, hemos asentado la bases para la construcción de SPA (single page applications).
Aquí dejo el enlace a la documentación oficial actualizada sobre los hooks.