15. Router: search params
Проблема с обычными search params
Заголовок раздела «Проблема с обычными search params»В стандартном веб-разработке URL параметры (?page=1&filter=active) — это просто строки.
Нет типизации, нет валидации, легко получить NaN или undefined.
TanStack Router решает это через validateSearch:
export const Route = createFileRoute('/users')({ validateSearch: (search: Record<string, unknown>) => ({ page: Number(search.page) || 1, filter: (search.filter as string) || '', sort: (search.sort as 'asc' | 'desc') || 'asc', view: (search.view as 'table' | 'grid') || 'table', }),})Теперь useSearch() возвращает { page: number; filter: string; sort: 'asc' | 'desc'; view: 'table' | 'grid' }.
Валидация с Zod
Заголовок раздела «Валидация с Zod»Для более сложной валидации используйте Zod схемы:
import { z } from 'zod'
const searchSchema = z.object({ page: z.number().min(1).catch(1), filter: z.string().optional().catch(''), sort: z.enum(['asc', 'desc']).catch('asc'),})
export const Route = createFileRoute('/users')({ validateSearch: searchSchema,})catch() в Zod — значение по умолчанию при неверном вводе. Без него невалидный URL вызовет ошибку.
useSearch
Заголовок раздела «useSearch»function UsersPage() { const { page, filter, sort } = Route.useSearch() // page: number // filter: string // sort: 'asc' | 'desc'}Обновление search params
Заголовок раздела «Обновление search params»import { useNavigate } from '@tanstack/react-router'
function UsersPage() { const navigate = useNavigate({ from: Route.fullPath }) const { page, filter } = Route.useSearch()
const setPage = (newPage: number) => { navigate({ search: (prev) => ({ ...prev, page: newPage }) }) }
const setFilter = (newFilter: string) => { // Сбрасываем страницу при изменении фильтра navigate({ search: (prev) => ({ ...prev, filter: newFilter, page: 1 }) }) }}Link с search params
Заголовок раздела «Link с search params»// Полная типизация! TypeScript проверит структуру search<Link to="/users" search={{ page: 2, filter: 'active', sort: 'desc' }}> Следующая страница</Link>
// Обновление одного параметра<Link to="." search={(prev) => ({ ...prev, sort: prev.sort === 'asc' ? 'desc' : 'asc' })}> Сортировка</Link>searchParamOptions
Заголовок раздела «searchParamOptions»Дополнительные опции для управления search params:
export const Route = createFileRoute('/users')({ validateSearch: (s) => ({ page: Number(s.page) || 1 }), search: { middlewares: [stripSearchParams({ page: 1 })], // Автоматически удаляет page=1 из URL (default значение) },})