React

React

Tutorial React: Custom Hooks para servicios compartidos

React y custom hooks: Aprende a crear custom hooks para reutilizar lógica compleja en servicios compartidos, mejorando la eficiencia y mantenibilidad de tus componentes React.

¿Qué es y cuando usar un Custom Hook?

Un Custom Hook en React es una función de JavaScript, cuyo nombre comienza con use, que permite reutilizar lógica de estado y efectos en componentes funcionales. Al encapsular comportamientos comunes, los custom hooks facilitan la compartición de lógica entre componentes sin necesidad de duplicar código, promoviendo así un desarrollo más limpio y mantenible. Al igual que los hooks de React integrados, los custom hooks pueden utilizar otros hooks, como useState, useEffect o useContext, para gestionar el estado o realizar efectos secundarios.

El uso de custom hooks es particularmente relevante cuando se necesita abstraer y reutilizar lógica compleja que se repite en varios componentes. Por ejemplo, si varios componentes necesitan realizar una solicitud HTTP y gestionar el estado de carga y errores, un custom hook puede encapsular esta lógica, proporcionando una interfaz sencilla para su reutilización. No solo se trata de compartir lógica, sino también de desacoplar componentes, haciendo que el código sea más legible y modular.

La creación de un custom hook implica simplemente definir una función que encapsule la lógica deseada. No hay una estructura especial necesaria más allá de seguir la convención de nombrado que comienza con use. Este enfoque se alinea con los principios de composición en React, permitiendo que los componentes se construyan a partir de piezas más pequeñas y reutilizables. Aquí un ejemplo básico de un custom hook para gestionar un contador:

// hooks/useContador.js
import { useState } from 'react';

export default function useContador(inicial = 0) {
  const [contador, setContador] = useState(inicial);

  const incrementar = () => setContador(contador + 1);
  const decrementar = () => setContador(contador - 1);
  const reiniciar = () => setContador(inicial);

  return { contador, incrementar, decrementar, reiniciar };
}

Este hook useContador encapsula la lógica de un contador con funciones para incrementar, decrementar y reiniciar su valor. Al utilizar este custom hook en un componente, se simplifica significativamente la gestión del estado del contador, manteniendo el componente más limpio y enfocado en su presentación.

Es crucial saber cuándo usar un custom hook. Si la lógica se utiliza en un solo componente, puede no ser necesario crear un custom hook. Sin embargo, cuando se detecta que la lógica se repite en múltiples componentes o es lo suficientemente compleja como para beneficiarse de una abstracción, un custom hook es adecuado. Además, al utilizar custom hooks, se mejora la separación de responsabilidades, permitiendo que los componentes se centren en la interfaz de usuario y la lógica de presentación, mientras que los hooks gestionan la lógica del estado y los efectos secundarios.

Creación de un custom hook básico

Para crear un custom hook básico en React, es esencial comprender que se trata de una función JavaScript que encapsula lógica de estado o efectos secundarios, permitiendo su reutilización en varios componentes. La convención de nomenclatura requiere que el nombre del hook comience con use, lo que facilita a React el seguimiento de las reglas de los hooks.

Supongamos que queremos crear un custom hook que gestione el estado de un toggle. Este hook puede ser útil en situaciones donde necesitemos alternar entre dos estados, como encender y apagar una función. El código para este custom hook podría verse así:

// hooks/useToggle.js
import { useState } from 'react';

export default function useToggle(estadoInicial = false) {
  const [estado, setEstado] = useState(estadoInicial);

  const toggle = () => setEstado(!estado);

  return [estado, toggle];
}

En este ejemplo, useToggle inicia con un estado booleano y proporciona una función toggle para alternar su valor. Este patrón es común y muy práctico para gestionar estados binarios en componentes funcionales.

Para utilizar este custom hook en un componente, simplemente importamos el hook y lo invocamos dentro del componente funcional. Aquí hay un ejemplo de cómo podría integrarse en un componente:

// components/ToggleComponent/ToggleComponent.jsx
import useToggle from '../../hooks/useToggle';

export default function ToggleComponent() {
  const [isToggled, toggle] = useToggle();

  return (
    <button onClick={toggle}>
      {isToggled ? 'Encendido' : 'Apagado'}
    </button>
  );
}

En este componente ToggleComponent, el botón utiliza el estado y la función proporcionados por useToggle. Cada vez que se hace clic en el botón, se alterna entre "Encendido" y "Apagado", demostrando cómo un custom hook puede simplificar la gestión del estado en componentes React.

La creación de custom hooks no se limita a lógica sencilla. Pueden ser tan complejos como se necesite, integrando otros hooks de React como useEffect o useContext para gestionar efectos secundarios o contexto global. La clave es encapsular la lógica que se repite o que es compleja para hacer el código más limpio y fácil de mantener. Este enfoque también promueve la composición, un principio fundamental en React, permitiendo que los componentes se construyan a partir de unidades más pequeñas y reutilizables.

Custom hook para solicitudes http

En React, un custom hook para gestionar solicitudes HTTP puede simplificar significativamente la interacción con APIs, permitiendo manejar estados de carga, errores y datos de forma eficiente. Este tipo de hook es particularmente útil cuando múltiples componentes necesitan realizar solicitudes similares, ya que encapsula la lógica de las solicitudes en un único lugar, promoviendo la reutilización y la consistencia.

Para crear un custom hook que maneje solicitudes HTTP, puedes utilizar useState para gestionar el estado de los datos, los errores y la carga, y useEffect para ejecutar la solicitud cuando el componente se monte o cuando cambien las dependencias. Aquí tienes un ejemplo de cómo podría implementarse un hook para realizar solicitudes GET:

// hooks/useFetch.js
import { useState, useEffect } from 'react';

export default function useFetch(url, datosInicial = null) {
  const [datos, setDatos] = useState(datosInicial);
  const [cargando, setCargando] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const abortController = new AbortController();

    const fetchData = async () => {
      setCargando(true);
      try {
        const respuesta = await fetch(url, { signal: abortController.signal });
        if (!respuesta.ok) {
          throw new Error(`Error HTTP: ${respuesta.status}`);
        }
        const datos = await respuesta.json();
        setDatos(datos);
      } catch (error) {
        if (error.name !== 'AbortError') {
          setError(error);
        }
      } finally {
        setCargando(false);
      }
    };

    fetchData();

    return () => {
      abortController.abort();
    };
  }, [url]);

  return { datos, cargando, error };
}

Este custom hook useFetch realiza una solicitud HTTP GET a la URL proporcionada. Utiliza un AbortController para cancelar la solicitud si el componente se desmonta antes de que la solicitud se complete, evitando posibles fugas de memoria. El hook devuelve un objeto con el estado de los datos, la carga y los errores, lo que permite a los componentes consumir esta información de manera sencilla.

Para utilizar este custom hook en un componente, simplemente importa el hook y pásale la URL de la API desde la cual deseas obtener datos. Aquí tienes un ejemplo de cómo integrar useFetch en un componente funcional:

// components/DatosComponent/DatosComponent.jsx
import useFetch from '../../hooks/useFetch';

export default function DatosComponent() {
  const { datos, cargando, error } = useFetch('https://fakestoreapi.com/products', []);

  if (cargando) return <p>Cargando...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {datos.map(item => (
        <li key={item.id}>{item.title}</li>
      ))}
    </ul>
  );
}

En este ejemplo, DatosComponent utiliza useFetch para obtener datos de una API. Mientras se cargan los datos, se muestra un mensaje de carga, y si ocurre un error, se muestra un mensaje de error. Una vez que los datos se han cargado con éxito, se renderiza una lista de elementos. Este enfoque no solo simplifica la gestión de las solicitudes HTTP, sino que también mejora la modularidad del código, permitiendo que los componentes se centren en la presentación y delegando la lógica de la solicitud al hook.

Buenas prácticas en la creación de custom hooks

Al desarrollar custom hooks en React, es crucial seguir ciertas prácticas para garantizar que el código sea eficiente, reutilizable y fácil de mantener. Un enfoque metódico en la creación de estos hooks no solo mejora la calidad del código, sino que también facilita su integración en proyectos más grandes y complejos.

En primer lugar, es esencial nombrar los hooks de manera clara y descriptiva. Un buen nombre debería reflejar la funcionalidad que proporciona el hook, comenzando siempre con el prefijo use. Esta convención no solo ayuda a identificar rápidamente los hooks, sino que también permite que React aplique las reglas de los hooks correctamente. Por ejemplo, un hook que gestiona el estado de un formulario podría llamarse useFormulario.

La encapsulación de lógica es otro aspecto fundamental. Un custom hook debe encapsular toda la lógica necesaria para una funcionalidad específica, evitando exponer detalles internos. Esto no solo mejora la separación de preocupaciones, sino que también permite a otros desarrolladores utilizar el hook sin necesidad de comprender su implementación interna. Por ejemplo, al crear un hook para gestionar el estado de autenticación, el hook debería manejar internamente el almacenamiento de tokens y la verificación de usuarios, exponiendo solo una API clara y simple.

La composición de hooks es una práctica recomendada que permite combinar múltiples hooks para crear funcionalidades más complejas. Un custom hook puede utilizar otros hooks personalizados o integrados de React, como useState o useEffect, para gestionar diferentes aspectos de la lógica. Al componer hooks, se pueden crear soluciones altamente modulares y reutilizables. Por ejemplo, un hook useDatosUsuario podría combinar useFetch para obtener datos y useState para gestionar el estado de carga y errores.

Es importante también gestionar adecuadamente las dependencias en hooks que utilizan useEffect. Las dependencias deben ser especificadas de manera precisa para evitar ejecuciones innecesarias o la falta de actualizaciones cuando cambian los valores relevantes. Un descuido en este aspecto puede llevar a problemas de rendimiento o a comportamientos inesperados. Por ejemplo, si un hook depende de una URL para realizar una solicitud HTTP, la URL debe incluirse en la lista de dependencias para asegurar que el efecto se ejecute cuando esta cambie.

El manejo de efectos secundarios es otro aspecto crucial. Si un custom hook realiza operaciones asíncronas, como solicitudes HTTP, es fundamental gestionar adecuadamente el ciclo de vida de estos efectos. Utilizar AbortController para cancelar solicitudes cuando el componente se desmonta es una práctica recomendada para evitar fugas de memoria. Asegúrate de limpiar los efectos secundarios en el retorno de la función useEffect para mantener la aplicación libre de errores.

Finalmente, la documentación clara y concisa es esencial para facilitar la comprensión y el uso de custom hooks por parte de otros desarrolladores. Proporcionar ejemplos de uso y una descripción de la API del hook ayuda a integrar rápidamente la funcionalidad en otros componentes. La documentación debe incluir detalles sobre los parámetros que acepta el hook y los valores que retorna, así como cualquier efecto secundario que pueda tener.

Certifícate en React con CertiDevs PLUS

Ejercicios de esta lección Custom Hooks para servicios compartidos

Evalúa tus conocimientos de esta lección Custom Hooks para servicios compartidos con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de React

Accede a todas las lecciones de React y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A React Y Su Ecosistema

React

Introducción Y Entorno

Instalar React Y Crear Nuevo Proyecto

React

Introducción Y Entorno

Introducción A Jsx

React

Componentes

Introducción A Componentes

React

Componentes

Componentes Funcionales

React

Componentes

Eventos En React

React

Componentes

Props Y Manejo De Datos Entre Componentes

React

Componentes

Renderizado Condicional

React

Componentes

Renderizado Iterativo Con Bucles

React

Componentes

Manejo De Clases Y Estilos

React

Componentes

Introducción A Los Hooks

React

Hooks

Estado Y Ciclo De Vida De Los Componentes

React

Hooks

Hooks Para Manejo De Estado Y Efectos Secundarios

React

Hooks

Hooks Para Gestión De Estado Complejo Y Contexto

React

Hooks

Hooks Para Optimización Y Actualizaciones Concurrentes

React

Hooks

Introducción A React Router

React

Navegación Y Enrutamiento

Definición Y Manejo De Rutas

React

Navegación Y Enrutamiento

Rutas Anidadas Y Rutas Dinámicas

React

Navegación Y Enrutamiento

Navegación Programática Y Redireccionamiento

React

Navegación Y Enrutamiento

Nuevos Métodos Create De React Router

React

Navegación Y Enrutamiento

Solicitudes Http Con Fetch Api

React

Interacción Http Con Backend

Solicitudes Http Con Axios

React

Interacción Http Con Backend

Estado Local Con Usestate Y Usereducer

React

Servicios Y Gestión De Estado

Estado Global Con Context Api

React

Servicios Y Gestión De Estado

Estado Global Con Redux Toolkit

React

Servicios Y Gestión De Estado

Custom Hooks Para Servicios Compartidos

React

Servicios Y Gestión De Estado

Certificados de superación de React

Supera todos los ejercicios de programación del curso de React y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender la utilidad de los custom hooks en React.
  • Aprender a crear un custom hook básico.
  • Aplicar custom hooks para gestionar lógicas comunes como contadores y toggles.
  • Implementar un custom hook para manejar solicitudes HTTP.
  • Seguir buenas prácticas en la creación de custom hooks.
  • Mejorar la modularidad y reutilización del código en React.