"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Gancho React personalizado para sincronizar o estado com o URL

Gancho React personalizado para sincronizar o estado com o URL

Publicado em 15/08/2024
Navegar:194

Custom React hook to sync state with the URL

Ao criar aplicativos React, geralmente é benéfico refletir o estado na URL. Isso não apenas torna o estado compartilhável, mas também permite que os usuários marquem ou atualizem páginas sem perder o contexto. Nesta postagem, criaremos um gancho React personalizado chamado useParamState em TypeScript. Este gancho funcionará como useState, mas também sincronizará o estado com os parâmetros de pesquisa na URL. É importante ressaltar que ele suportará valores de objetos complexos.

Por que usarParamState?

O gancho useSearchParams do React Router é excelente para gerenciar parâmetros de pesquisa de URL, mas sincronizá-los com o estado do componente pode ser complicado. O gancho useParamState resolve isso por:

  • Fornecendo uma API simples semelhante a useState.
  • Sincronizando automaticamente o estado com os parâmetros de pesquisa de URL.
  • Suporte a tipos complexos, incluindo objetos.

Pré-requisitos

  • Compreensão básica de React, TypeScript e React Router.
  • Familiaridade com useState e useEffect.

Implementando useParamState

Etapa 1: Configurando o Projeto

(Isso pressupõe que você já saiba como configurar um projeto de reação, se não, vá para o Vite)

Certifique-se de ter o react-router-dom instalado:

npm install react-router-dom

Etapa 2: o gancho useParamState

Veja como você pode implementar o 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;


Como funciona

Inicialização:

O gancho começa verificando se o parâmetro de pesquisa especificado existe na URL. Se isso acontecer, o gancho o analisa e o usa como estado inicial. Caso contrário, ele retornará ao defaultValue fornecido.

Atualização do estado:

A função setParamState atualiza o estado interno e o parâmetro de pesquisa na URL. Ele usa JSON.stringify para serializar o estado, permitindo-nos armazenar objetos complexos na URL.

Tipo Suporte:

O gancho suporta vários tipos (string, número, booleano e objeto) aproveitando os genéricos do TypeScript e a análise JSON.

Etapa 3: usando useParamState

Vamos ver como você pode usar useParamState em um componente 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;

Etapa 4: testando o gancho

Para garantir que o gancho useParamState funcione conforme o esperado, você pode escrever testes de unidade 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' });
});

Conclusão

O gancho useParamState simplifica o processo de sincronização de estado com parâmetros de pesquisa de URL, tornando seus aplicativos React mais robustos e fáceis de usar. Com suporte para tipos complexos como objetos, esse gancho é uma ferramenta poderosa para gerenciar o estado que precisa persistir durante as recargas de páginas ou ser compartilhado por meio de URLs.

Você pode estender ainda mais esse gancho para lidar com estruturas de dados ainda mais complexas, mas para a maioria dos casos de uso, esta implementação atenderá às suas necessidades.

(Comente o artigo para que eu possa melhorar e corrigir quaisquer erros que possa ter cometido, desde já agradeço.)

Sinta-se à vontade para me seguir em outras plataformas também

  • Linkedin

  • Github

  • Instagram

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/mr_mornin_star/custom-react-hook-to-sync-state-with-the-url-4b6p?1 Se houver alguma violação, entre em contato com [email protected] para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3