En React, los Hooks son funciones especiales que te permiten «enganchar» características de React, como el estado y el ciclo de vida, en componentes funcionales. Antes de los Hooks, estas características solo estaban disponibles en componentes de clase. Los Hooks fueron introducidos en la versión 16.8 para permitir que los componentes funcionales tengan capacidad para manejar estado y efectos secundarios.
useState es el primer Hook que exploraremos. Imagina que estás construyendo una aplicación que necesita llevar un contador. Tradicionalmente, podrías pensar en usar un componente de clase, pero con useState puedes hacerlo directamente en un componente funcional.
import React, { useState } from 'react';
function Counter() {
// Inicializa el estado con un valor de 0
const [count, setCount] = useState(0);
return (
Has hecho clic {count} veces
);
}
Aquí, useState
te da dos cosas: count
es el valor actual del estado, y setCount
es una función que te permite actualizar ese estado.
El siguiente Hook esencial es useEffect. Es como un caballero que se encarga de realizar tareas fuera del flujo principal de tu componente, como cargar datos, suscribirse a servicios, o limpiar recursos, similar a cómo lo harías en los métodos de ciclo de vida en componentes de clase.
import React, { useState, useEffect } from 'react';
function UserData() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/user')
.then(response => response.json())
.then(data => setData(data));
}, []); // El array vacío indica que esto se ejecuta solo una vez, al montar el componente.
return (
{data ? Nombre: {data.name}
: Cargando...
}
);
}
En este ejemplo, useEffect
se utiliza para cargar datos de un usuario apenas el componente se monta.
Imagina que eres un chef en tu propia cocina de código, y hasta ahora, has estado usando ingredientes estándar que React te ofrece. Pero, ¿qué sucede cuando quieres algo específico que no viene en el paquete básico? Aquí es donde los Hooks personalizados entran en juego, permitiéndote crear tus propios ingredientes especiales para hacer que tus aplicaciones sean aún más deliciosas.
Un Hook personalizado es básicamente una función que tú creas para reutilizar lógica de estado o efectos entre múltiples componentes. React no ofrece una API específica para crearlos; simplemente usas los Hooks existentes de React de una manera que encapsule la lógica que quieres reutilizar.
Supongamos que tienes varios componentes en tu aplicación que necesitan acceder a la ubicación del usuario. En lugar de duplicar la lógica en cada componente, puedes crear un Hook personalizado llamado useLocation
.
import { useState, useEffect } from 'react';
function useLocation() {
const [location, setLocation] = useState({ latitude: null, longitude: null });
const [error, setError] = useState(null);
useEffect(() => {
if (!navigator.geolocation) {
setError('Geolocalización no soportada por este navegador.');
return;
}
function onSuccess(position) {
setLocation({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
}
function onError(error) {
setError(error.message);
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}, []);
return [location, error];
}
Este Hook personalizado usa useState
para manejar el estado de la ubicación y un posible error, y useEffect
para ejecutar la obtención de la ubicación cuando el componente se monta. Ahora, cualquier componente que necesite la ubicación del usuario puede usar useLocation
.
import React from 'react';
import useLocation from './useLocation'; // Asumiendo que está en un archivo llamado useLocation.js
function App() {
const [location, error] = useLocation();
return (
{error ? (
Error: {error}
) : (
Ubicación: Latitud {location.latitude}, Longitud {location.longitude}
)}
);
}
Ahora que ya hemos visto los Hooks básicos y cómo crear Hooks personalizados, vamos a profundizar en una herramienta muy útil para manejar el estado global en aplicaciones React: el Contexto con el Hook useContext
.
Imagina que tienes una gran casa con muchas habitaciones (componentes) y quieres que todos en la casa sepan si la puerta principal está cerrada o abierta (un dato global). Podrías ir de habitación en habitación diciéndolo, o simplemente podrías poner un gran cartel en la entrada que todos puedan ver. Eso es básicamente lo que hace el Contexto en React: proporciona una forma de compartir valores entre componentes sin tener que pasar explícitamente las props a través de cada nivel del árbol de componentes.
Primero, debes crear un Contexto que será el «cartel» en nuestra analogía. Esto se hace con React.createContext()
.
import React, { createContext, useState, useContext } from 'react';
// Crea un Contexto para el estado de la puerta
const DoorContext = createContext();
// Componente proveedor que establece el valor del contexto
function DoorProvider({ children }) {
const [isOpen, setIsOpen] = useState(false); // Estado inicial de la puerta: cerrada
const toggleDoor = () => {
setIsOpen(!isOpen); // Cambia el estado de la puerta
};
// El valor que se pasa a todos los consumidores del contexto
return (
{children}
);
}
Ahora, cualquier componente que necesite acceder al estado de la puerta o cambiarlo, puede usar el Hook useContext
para «leer el cartel».
function DoorStatus() {
const { isOpen } = useContext(DoorContext); // Usar useContext para acceder al contexto
return La puerta está {isOpen ? 'abierta' : 'cerrada'}.
;
}
function DoorToggle() {
const { toggleDoor } = useContext(DoorContext); // Acceder a la función para cambiar el estado
return ;
}
Finalmente, asegúrate de envolver tus componentes en el DoorProvider
para que puedan acceder al contexto creado.
function App() {
return (
Control de la puerta principal
);
}