«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Пользовательский крючок React для синхронизации состояния с URL-адресом

Пользовательский крючок React для синхронизации состояния с URL-адресом

Опубликовано 15 августа 2024 г.
Просматривать:983

Custom React hook to sync state with the URL

При создании приложений React часто бывает полезно отразить состояние в URL-адресе. Это не только делает состояние доступным для совместного использования, но также позволяет пользователям добавлять закладки или обновлять страницы, не теряя их контекста. В этом посте мы создадим собственный хук React под названием useParamState в TypeScript. Этот хук будет работать так же, как useState, но он также будет синхронизировать состояние с параметрами поиска в URL-адресе. Важно отметить, что он будет поддерживать сложные значения объектов.

Зачем использоватьParamState?

Хук useSearchParams в React Router отлично подходит для управления параметрами поиска URL-адресов, но их синхронизация с состоянием компонента может быть затруднительной. Хук useParamState решает эту проблему следующим образом:

  • Предоставление простого API, похожего на useState.
  • Автоматическая синхронизация состояния с параметрами поиска URL.
  • Поддержка сложных типов, включая объекты.

Предварительные условия

  • Базовое понимание React, TypeScript и React Router.
  • Знакомство с useState и useEffect.

Реализация useParamState

Шаг 1: Настройка проекта

( Предполагается, что вы уже знаете, как настроить проект реагирования, в противном случае перейдите на Vite)

Убедитесь, что у вас установлен response-router-dom:

npm install react-router-dom

Шаг 2. Хук useParamState

Вот как можно реализовать хук 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;


Как это работает

Инициализация:

Хук начинается с проверки наличия указанного параметра поиска в URL-адресе. Если это так, перехватчик анализирует его и использует в качестве начального состояния. В противном случае он возвращается к предоставленному значению по умолчанию.

Обновление состояния:

Функция setParamState обновляет как внутреннее состояние, так и параметр поиска в URL-адресе. Он использует JSON.stringify для сериализации состояния, что позволяет нам хранить сложные объекты в URL-адресе.

Тип поддержки:

Хук поддерживает различные типы (строку, число, логическое значение и объект), используя дженерики TypeScript и анализ JSON.

Шаг 3. Использование useParamState

Давайте посмотрим, как можно использовать useParamState в компоненте 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;

Шаг 4: Проверка крючка

Чтобы убедиться, что перехват useParamState работает должным образом, вы можете написать модульные тесты, используя @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' });
});

Заключение

Хук useParamState упрощает процесс синхронизации состояния с параметрами поиска URL-адресов, делая ваши приложения React более надежными и удобными для пользователя. Благодаря поддержке сложных типов, таких как объекты, этот хук представляет собой мощный инструмент для управления состоянием, которое должно сохраняться при перезагрузке страницы или передаваться через URL-адреса.

Вы можете расширить этот хук для обработки еще более сложных структур данных, но в большинстве случаев эта реализация удовлетворит ваши потребности.

( Прокомментируйте статью, чтобы я мог сделать ее лучше и исправить ошибки, которые я мог допустить, заранее спасибо. )

Не стесняйтесь подписываться на меня и на других платформах

  • Linkedin

  • Github

  • Инстаграм

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/mr_mornin_star/custom-react-hook-to-sync-state-with-the-url-4b6p?1 Если есть какие-либо нарушения, пожалуйста, свяжитесь с [email protected] удалить его
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3