"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Gancho de React personalizado para sincronizar el estado con la URL

Gancho de React personalizado para sincronizar el estado con la URL

Publicado el 2024-08-15
Navegar:198

Custom React hook to sync state with the URL

Al crear aplicaciones React, a menudo es beneficioso reflejar el estado en la URL. Esto no sólo hace que el estado se pueda compartir sino que también permite a los usuarios marcar o actualizar páginas sin perder su contexto. En esta publicación, crearemos un gancho de React personalizado llamado useParamState en TypeScript. Este enlace funcionará como useState, pero también sincronizará el estado con los parámetros de búsqueda en la URL. Es importante destacar que admitirá valores de objetos complejos.

¿Por qué utilizarParamState?

El gancho useSearchParams de React Router es excelente para administrar los parámetros de búsqueda de URL, pero sincronizarlos con el estado del componente puede ser engorroso. El gancho useParamState soluciona esto mediante:

  • Proporcionando una API simple similar a useState.
  • Sincronizando automáticamente el estado con los parámetros de búsqueda de URL.
  • Compatible con tipos complejos, incluidos objetos.

Requisitos previos

  • Comprensión básica de React, TypeScript y React Router.
  • Familiaridad con useState y useEffect.

Implementando useParamState

Paso 1: configurar el proyecto

(Esto supone que ya sabes cómo configurar un proyecto de reacción, si no, dirígete a Vite)

Asegúrate de tener instalado react-router-dom:

npm install react-router-dom

Paso 2: El gancho useParamState

A continuación se explica cómo implementar el gancho useParamState:

import { useCallback, useState } from 'react';
import { useSearchParams } from 'react-router-dom';

/**
 * A custom hook that syncs state with a URL search parameter.
 * Supports string, number, boolean, and object values.
 * @param key The search parameter key to sync with.
 * @param defaultValue The default value for the state.
 * @returns A stateful value, and a function to update it.
 */
function useParamState(
  key: string,
  defaultValue: T
): [T, (newValue: Partial | T) => void] {
  const [searchParams, setSearchParams] = useSearchParams();
  const paramValue = searchParams.get(key);

  const [state, setState] = useState(() => {
    if (paramValue === null) {
      return defaultValue;
    }
    try {
      return JSON.parse(paramValue) as T;
    } catch {
      return paramValue as T;
    }
  });

  const setParamState = useCallback(
    (newValue: Partial | T) => {
      const updatedValue = typeof newValue === 'object' && !Array.isArray(newValue)
        ? { ...state, ...newValue }
        : newValue;

      setState(updatedValue as T);
      const newSearchParams = new URLSearchParams(searchParams);
      newSearchParams.set(key, JSON.stringify(updatedValue));
      setSearchParams(newSearchParams);
    },
    [key, searchParams, setSearchParams, state]
  );

  return [state, setParamState];
}

export default useParamState;


Cómo funciona

Inicialización:

El enlace comienza verificando si el parámetro de búsqueda especificado existe en la URL. Si es así, el gancho lo analiza y lo utiliza como estado inicial. De lo contrario, vuelve al valor predeterminado proporcionado.

Actualización del estado:

La función setParamState actualiza tanto el estado interno como el parámetro de búsqueda en la URL. Utiliza JSON.stringify para serializar el estado, lo que nos permite almacenar objetos complejos en la URL.

Tipo de soporte:

El gancho admite varios tipos (cadena, número, booleano y objeto) aprovechando los genéricos de TypeScript y el análisis JSON.

Paso 3: usar useParamState

Veamos cómo puedes usar useParamState en un componente de React:

import React from 'react';
import useParamState from './useParamState';

interface FilterState {
  status: string;
  sortBy: string;
}

const MyComponent: React.FC = () => {
  const [filter, setFilter] = useParamState('filter', {
    status: 'all',
    sortBy: 'date',
  });

  return (
    

Current Filter: {filter.status}, Sort by: {filter.sortBy}

); }; export default MyComponent;

Paso 4: probar el gancho

Para garantizar que el gancho useParamState funcione como se esperaba, puede escribir pruebas unitarias usando @testing-library/react:

import { renderHook, act } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import useParamState from './useParamState';

interface FilterState {
  status: string;
  sortBy: string;
}

test('should sync object state with search params', () => {
  const wrapper = ({ children }: { children: React.ReactNode }) => (
    {children}
  );

  const { result } = renderHook(() => useParamState('filter', { status: 'all', sortBy: 'date' }), { wrapper });

  // Initial state
  expect(result.current[0]).toEqual({ status: 'all', sortBy: 'date' });

  // Update state and URL
  act(() => {
    result.current[1]({ status: 'active', sortBy: 'priority' });
  });

  // Updated state
  expect(result.current[0]).toEqual({ status: 'active', sortBy: 'priority' });
});

Conclusión

El gancho useParamState simplifica el proceso de sincronización del estado con los parámetros de búsqueda de URL, lo que hace que sus aplicaciones React sean más sólidas y fáciles de usar. Con soporte para tipos complejos como objetos, este enlace es una poderosa herramienta para administrar el estado que debe persistir durante las recargas de la página o compartirse a través de URL.

Puedes ampliar aún más este enlace para manejar estructuras de datos aún más complejas, pero para la mayoría de los casos de uso, esta implementación cubrirá tus necesidades.

(Comente el artículo para poder mejorarlo y corregir cualquier error que pueda haber cometido, gracias de antemano).

Siéntete libre de seguirme también en otras plataformas

  • Linkedin

  • Github

  • Instagram

Declaración de liberación Este artículo se reproduce en: https://dev.to/mr_mornin_star/custom-react-hook-to-sync-state-with-the-url-4b6p?1 Si hay alguna infracción, comuníquese con [email protected] para borrarlo
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3