Валидация параметров маршрута

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


Определение параметров маршрута с типизацией

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

import { createRouter, createRoute } from '@tanstack/router';

const userRoute = createRoute({
  path: '/user/:userId',
  validate: {
    userId: (value) => {
      const id = Number(value);
      if (Number.isNaN(id) || id <= 0) {
        throw new Error('Invalid userId');
      }
      return id;
    }
  },
  component: UserComponent,
});

Ключевые моменты:

  • validate принимает объект, где ключи — это имена параметров маршрута, а значения — функции проверки.
  • Функция проверки должна возвращать корректное значение или выбрасывать ошибку при недопустимом формате.
  • После валидации параметр автоматически доступен в компоненте в корректном типе.

Валидация нескольких параметров

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

const postRoute = createRoute({
  path: '/user/:userId/post/:postId',
  validate: {
    userId: (value) => {
      const id = Number(value);
      if (Number.isNaN(id) || id <= 0) throw new Error('Invalid userId');
      return id;
    },
    postId: (value) => {
      const id = Number(value);
      if (Number.isNaN(id) || id <= 0) throw new Error('Invalid postId');
      return id;
    },
  },
  component: PostComponent,
});

Функции валидации выполняются при переходе на маршрут, и ошибки автоматически блокируют навигацию, предотвращая рендеринг компонента с некорректными данными.


Валидация query-параметров

TanStack Router также поддерживает проверку query-параметров через схему в маршруте:

const searchRoute = createRoute({
  path: '/search',
  validateSearch: (query) => {
    const page = Number(query.page || 1);
    if (Number.isNaN(page) || page < 1) throw new Error('Invalid page number');
    return { page };
  },
  component: SearchComponent,
});

Особенности:

  • validateSearch обрабатывает объект query-параметров.
  • Можно задавать значения по умолчанию и преобразовывать строки из URL в нужные типы (например, числа или булевы значения).

Использование схем для сложной валидации

Для более сложных правил часто используют библиотеки схем, например zod или yup:

import { z } from 'zod';

const schema = z.object({
  userId: z.number().positive(),
  postId: z.number().positive(),
});

const postRoute = createRoute({
  path: '/user/:userId/post/:postId',
  validate: (params) => schema.parse({
    userId: Number(params.userId),
    postId: Number(params.postId),
  }),
  component: PostComponent,
});

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

  • Централизованная валидация для всех маршрутов.
  • Автоматическая генерация ошибок с понятными сообщениями.
  • Возможность комбинировать валидацию параметров и query-параметров.

Обработка ошибок валидации

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

const router = createRouter({
  routes: [userRoute, postRoute],
  onError: (error) => {
    console.error('Navigation error:', error.message);
    // Можно перенаправить на страницу ошибки
    router.navigate('/error');
  },
});

Рекомендации:

  • Всегда обрабатывать ошибки, чтобы избежать некорректного рендеринга компонентов.
  • Локальные ошибки можно перехватывать на уровне компонента через useRouteError.

Валидация вложенных маршрутов

Для вложенных маршрутов валидация параметров распространяется рекурсивно:

const appRoute = createRoute({ path: '/', component: AppLayout });
const userSettingsRoute = createRoute({
  path: 'user/:userId/settings',
  parent: appRoute,
  validate: {
    userId: (value) => Number(value),
  },
  component: UserSettings,
});
  • Параметры родительского маршрута автоматически доступны для дочернего.
  • Можно комбинировать валидацию на уровне родителя и дочернего маршрута.

Итоговые рекомендации по валидации

  • Всегда преобразовывать параметры к нужным типам внутри функций валидации.
  • Для сложных правил использовать схемы (zod, yup) вместо ручного кода.
  • Обрабатывать ошибки валидации глобально и локально.
  • Проверять как path-параметры, так и query-параметры для целостности данных маршрута.
  • Вложенные маршруты наследуют параметры и валидацию, что позволяет строить масштабируемую архитектуру маршрутизации.