Параметры поиска (search params)

TanStack Router предоставляет мощный и гибкий механизм работы с URL-параметрами, включая параметры поиска. Параметры поиска — это часть URL, которая следует за знаком ? и используется для передачи данных через строку запроса, например: /products?category=books&page=2. TanStack Router позволяет работать с ними декларативно и типобезопасно, обеспечивая удобное управление состоянием маршрутов.

Определение и привязка search params

Параметры поиска можно определить при создании маршрута с помощью свойства searchSchema или search. Они поддерживают типизацию и валидацию. Пример определения маршрута с параметрами поиска:

import { createRouter, Route } from '@tanstack/router';
import { z } from 'zod';

const productRoute = new Route({
  getPath: () => '/products',
  searchSchema: z.object({
    category: z.string().optional(),
    page: z.number().default(1),
  }),
  component: ProductPage,
});

В данном примере:

  • category — необязательный параметр, который может использоваться для фильтрации продуктов по категории.
  • page — числовой параметр с значением по умолчанию 1.

searchSchema использует библиотеку zod для строгой типизации и валидации данных, что предотвращает ошибки при работе с некорректными параметрами поиска.

Получение и использование параметров поиска в компоненте

Для доступа к параметрам поиска внутри компонента используется хук useSearch. Он возвращает объект с актуальными значениями параметров и позволяет отслеживать их изменения:

import { useSearch } from '@tanstack/router';

function ProductPage() {
  const search = useSearch({ route: productRoute });

  console.log(search.category); // выводит категорию из URL
  console.log(search.page); // выводит текущую страницу

  return (
    <div>
      <h1>Товары категории: {search.category || 'Все'}</h1>
      <p>Страница: {search.page}</p>
    </div>
  );
}

Хук useSearch автоматически преобразует типы параметров, учитывая searchSchema. Если параметр отсутствует в URL, будет использовано значение по умолчанию.

Изменение параметров поиска

TanStack Router предоставляет метод navigate для изменения параметров поиска без полной перезагрузки страницы. Это особенно полезно для фильтров и пагинации:

import { useNavigate } from '@tanstack/router';

function Pagination() {
  const navigate = useNavigate({ from: productRoute });

  const goToPage = (pageNumber) => {
    navigate({ search: { page: pageNumber } });
  };

  return (
    <div>
      <button onCl ick={() => goToPage(1)}>1</button>
      <button onCl ick={() => goToPage(2)}>2</button>
    </div>
  );
}

При вызове navigate с новым объектом search URL обновляется, а компонент получает новые значения параметров поиска через useSearch, что делает работу с состоянием маршрутов декларативной и реактивной.

Поддержка сложных типов

Помимо простых строк и чисел, параметры поиска могут быть массивами, объектами или булевыми значениями. TanStack Router автоматически сериализует и десериализует их в строку URL и обратно:

const filterRoute = new Route({
  getPath: () => '/filter',
  searchSchema: z.object({
    tags: z.array(z.string()).optional(),
    available: z.boolean().optional(),
  }),
  component: FilterPage,
});

Для массивов и объектов URL будет выглядеть следующим образом: /filter?tags=red,blue&available=true. Хук useSearch преобразует их обратно в массив или булев тип.

Совместная работа с динамическими сегментами

Параметры поиска могут использоваться одновременно с динамическими сегментами URL:

const userRoute = new Route({
  getPath: ({ userId }) => `/users/${userId}`,
  searchSchema: z.object({
    tab: z.string().optional(),
  }),
  component: UserPage,
});

URL /users/123?tab=posts позволяет извлекать и динамический сегмент userId, и параметр поиска tab в одном компоненте:

function UserPage({ params }) {
  const search = useSearch({ route: userRoute });
  console.log(params.userId); // 123
  console.log(search.tab); // posts
}

Реактивное обновление при изменении search params

TanStack Router отслеживает изменения параметров поиска и автоматически вызывает перерендер компонента. Это позволяет создавать интерактивные интерфейсы, где фильтры и сортировка обновляются без перезагрузки страницы. Например:

function FilteredList() {
  const search = useSearch({ route: filterRoute });

  useEffect(() => {
    fetchItems({ tags: search.tags, available: search.available });
  }, [search.tags, search.available]);

  return <ItemList />;
}

Каждое изменение параметров поиска вызывает новый вызов fetchItems, обеспечивая синхронизацию интерфейса с URL.

Декларативная навигация с search params

TanStack Router поддерживает декларативные ссылки через компонент Link с указанием параметров поиска:

import { Link } from '@tanstack/router';

<Link to={productRoute} search={{ category: 'books', page: 2 }}>
  Книги, страница 2
</Link>

URL обновляется автоматически, а компонент ProductPage получает актуальные значения category и page через useSearch.

Преимущества использования searchSchema

  • Типизация и валидация: ошибки в параметрах поиска выявляются на этапе компиляции или рантайма.
  • Реактивность: изменения параметров автоматически обновляют компонент.
  • Декларативность: маршруты полностью описывают, какие параметры ожидаются.
  • Совместимость с динамическими сегментами: search params легко комбинируются с динамическими путями.

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