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

1. Создание хука useURLStorage.ts

Хук будет извлекать параметры из URL, синхронизировать их с внутренним состоянием приложения и обновлять URL при изменении состояния.

// hooks/useURLStorage.ts
import { useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import { StoreApi } from "zustand";
 
type URLStorageParams = {
  searchText?: string;
  page?: number;
  filters?: string;
};
 
const useURLStorage = (store: StoreApi<URLStorageParams>) => {
  const [searchParams, setSearchParams] = useSearchParams();
 
  // Синхронизация состояния из URL
  useEffect(() => {
    const params: URLStorageParams = {
      searchText: searchParams.get("searchText") || undefined,
      page: searchParams.get("page")
        ? Number(searchParams.get("page"))
        : undefined,
      filters: searchParams.get("filters") || undefined,
    };
 
    // Обновляем состояние стора
    store.setState(params);
  }, [searchParams, store]);
 
  // Обновление URL при изменении состояния
  useEffect(() => {
    const state = store.getState();
    const newParams = new URLSearchParams();
 
    if (state.searchText) newParams.set("searchText", state.searchText);
    if (state.page) newParams.set("page", state.page.toString());
    if (state.filters) newParams.set("filters", state.filters);
 
    setSearchParams(newParams);
  }, [store, setSearchParams]);
};
 
export default useURLStorage;
2. Использование хука в главном компоненте App.tsx

Хук подключается к стору и синхронизирует его состояние с URL.

// App.tsx
import React from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import useURLStorage from "./hooks/useURLStorage";
import useSearchStore from "./stores/SearchStore";
import SearchComponent from "./components/SearchComponent";
import PaginationComponent from "./components/PaginationComponent";
 
const App = () => {
  const searchStore = useSearchStore();
  useURLStorage(searchStore);
 
  return (
    <Router>
      <Routes>
        <Route
          path="/"
          element={
            <>
              <SearchComponent />
              <PaginationComponent />
            </>
          }
        />
      </Routes>
    </Router>
  );
};
 
export default App;
3. Пример стора SearchStore.ts

Создайте стор, который будет хранить состояние поиска, пагинации и фильтров.

// stores/SearchStore.ts
import create from "zustand";
 
type SearchState = {
  searchText?: string;
  page?: number;
  filters?: string;
  setSearchText: (text: string) => void;
  setPage: (page: number) => void;
  setFilters: (filters: string) => void;
};
 
const useSearchStore = create<SearchState>((set) => ({
  searchText: undefined,
  page: undefined,
  filters: undefined,
  setSearchText: (text) => set({ searchText: text }),
  setPage: (page) => set({ page }),
  setFilters: (filters) => set({ filters }),
}));
 
export default useSearchStore;
4. Пример использования в компонентах

Компоненты могут использовать стор для управления состоянием, которое автоматически синхронизируется с URL.

// components/SearchComponent.tsx
import React from "react";
import useSearchStore from "../stores/SearchStore";
 
const SearchComponent = () => {
  const { searchText, setSearchText } = useSearchStore();
 
  return (
    <div>
      <input
        type="text"
        value={searchText || ""}
        onChange={(e) => setSearchText(e.target.value)}
        placeholder="Поиск..."
      />
    </div>
  );
};
 
export default SearchComponent;
// components/PaginationComponent.tsx
import React from "react";
import useSearchStore from "../stores/SearchStore";
 
const PaginationComponent = () => {
  const { page, setPage } = useSearchStore();
 
  return (
    <div>
      <button onClick={() => setPage((page || 1) - 1)}>Назад</button>
      <span>Страница: {page || 1}</span>
      <button onClick={() => setPage((page || 1) + 1)}>Вперед</button>
    </div>
  );
};
 
export default PaginationComponent;
Основные моменты:
  • Хук useURLStorage синхронизирует состояние приложения с URL.
  • Стор SearchStore хранит состояние поиска, пагинации и фильтров.
  • Компоненты используют стор для управления состоянием, которое автоматически отражается в URL.

Этот подход улучшает масштабируемость, уменьшает связанность компонентов и упрощает работу с URL.


Назад