TanStack Router предоставляет мощный и гибкий способ управления маршрутами в приложениях на JavaScript и TypeScript. Одной из ключевых возможностей является работа со сложными параметрами поиска (query parameters), которые выходят за рамки простых строк или чисел и позволяют передавать структурированные данные, фильтры, массивы и объекты.
Для работы с параметрами поиска в TanStack Router используются
объекты типа searchSchema, которые позволяют строго
типизировать данные, проходящие через URL. В отличие от
стандартных строковых параметров, query-параметры можно представить как
объект с заранее определёнными полями.
import { createRouter, Route } from '@tanstack/router';
import { z } from 'zod';
const searchSchema = z.object({
filter: z.string().optional(),
page: z.number().default(1),
tags: z.array(z.string()).optional(),
});
const route = new Route({
path: '/items',
searchSchema,
});
В этом примере:
filter — строковый фильтр, может отсутствовать;page — числовой параметр с дефолтным значением 1;tags — массив строк, необязательный.Использование zod позволяет не только проверять тип
данных, но и автоматически приводить их к нужным типам при чтении из
URL.
TanStack Router позволяет передавать сложные
структуры, такие как массивы и объекты, через параметры поиска.
Для массивов рекомендуется использовать стандартную сериализацию через
[], а для объектов — JSON-сериализацию.
const route = new Route({
path: '/search',
searchSchema: z.object({
categories: z.array(z.string()).optional(),
filters: z.string().transform(JSON.parse).optional(),
}),
});
// Пример URL:
// /search?categories[]=books&categories[]=electronics&filters={"priceRange":[10,100]}
При таком подходе:
categories[] автоматически преобразуется в массив;filters хранится как JSON-строка и при загрузке
страницы десериализуется в объект.Важно правильно обрабатывать сериализацию и десериализацию, чтобы избежать ошибок при работе с объектами сложной структуры.
Для обновления query-параметров используется метод
router.navigate, который позволяет изменять только
нужные параметры, не ломая остальные.
router.navigate({
to: '/items',
search: prev => ({
...prev,
page: 2,
tags: ['new', 'popular'],
}),
});
Ключевые моменты:
...prev).Сложные query-параметры легко комбинировать с динамическими
сегментами маршрута. Например, можно иметь маршрут
/users/:userId/items и одновременно управлять фильтрами
через параметры поиска.
const userItemsRoute = new Route({
path: '/users/:userId/items',
searchSchema: z.object({
sortBy: z.enum(['name', 'date']).default('name'),
tags: z.array(z.string()).optional(),
}),
});
Использование таких маршрутов позволяет:
Для реактивного UI удобно использовать хуки, которые TanStack Router предоставляет для query-параметров:
const [searchParams, setSearchParams] = useSearchParams(userItemsRoute);
setSearchParams(prev => ({
...prev,
sortBy: 'date',
tags: [...(prev.tags || []), 'featured'],
}));
Преимущества такого подхода:
encodeURIComponent/decodeURIComponent.undefined в URL.zod или
superstruct — обеспечивает безопасность данных и
удобство автокомплита.