Общие элементы интерфейса

TanStack Router представляет собой современный маршрутизатор для JavaScript и TypeScript-приложений, ориентированный на гибкость и строгую типизацию. В основе работы лежит определение маршрутов через объекты, где каждый маршрут описывается набором свойств: путь, компонент и дочерние маршруты.

import { createRouter, Route } from '@tanstack/router';
import { HomePage, AboutPage } from './pages';

const router = createRouter({
  routes: [
    new Route({
      path: '/',
      component: HomePage,
    }),
    new Route({
      path: '/about',
      component: AboutPage,
    }),
  ],
});

Ключевой момент — маршруты можно вложенно объединять, создавая иерархию, где дочерний маршрут наследует путь родителя. Это позволяет управлять структурой приложения централизованно.


Объект маршрута

Каждый маршрут представляет собой объект с набором обязательных и опциональных свойств:

  • path — строка, определяющая URL-шаблон, поддерживает параметры (/users/:id) и вложенные пути.
  • component — React-компонент или функция, возвращающая JSX.
  • loader — асинхронная функция для загрузки данных до рендеринга компонента.
  • action — обработчик форм и POST-запросов.
  • children — массив вложенных маршрутов.
  • meta — объект для хранения произвольной информации, например прав доступа.
new Route({
  path: '/users/:id',
  component: UserProfile,
  loader: async ({ params }) => {
    return fetch(`/api/users/${params.id}`).then(res => res.json());
  },
  meta: { requiresAuth: true },
});

Использование loader позволяет предзагружать данные, а meta предоставляет гибкий способ добавлять информацию для авторизации, отслеживания состояния или SEO.


Навигация между маршрутами

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

  • useRouter() — возвращает объект маршрутизатора, через который можно программно менять путь.
  • useNavigate() — позволяет создавать функции навигации с поддержкой replace или push.
  • <Link> — компонент для декларативной навигации с обработкой активного состояния.
import { Link, useNavigate } from '@tanstack/router';

function Navigation() {
  const navigate = useNavigate();
  
  return (
    <nav>
      <Link to="/">Главная</Link>
      <Link to="/about">О нас</Link>
      <button onCl ick={() => navigate('/contact')}>Контакты</button>
    </nav>
  );
}

Особенность TanStack Router — поддержка оптимистичной навигации и отмены запросов, что важно при асинхронных операциях.


Параметры маршрутов и query

TanStack Router предоставляет удобный способ работы с динамическими сегментами URL:

  • params — объект с именованными параметрами пути.
  • search — объект с query-параметрами (?page=2&sort=desc).
  • useParams() и useSearch() — hooks для получения данных внутри компонента.
import { useParams, useSearch } from '@tanstack/router';

function UserPage() {
  const params = useParams();
  const search = useSearch();

  return (
    <div>
      <h1>Пользователь {params.id}</h1>
      <p>Страница {search.page}</p>
    </div>
  );
}

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


Обработка ошибок и fallback

В TanStack Router есть встроенные механизмы глобальной и локальной обработки ошибок. Для каждого маршрута можно задать errorComponent и pendingComponent:

new Route({
  path: '/profile',
  component: ProfilePage,
  loader: async () => fetch('/api/profile').then(r => r.json()),
  errorComponent: ProfileError,
  pendingComponent: ProfileLoader,
});
  • errorComponent рендерится, если loader или action выбрасывают исключение.
  • pendingComponent отображается до завершения асинхронной операции.

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


Логика вложенных интерфейсов

Важное преимущество TanStack Router — сегментация интерфейса на вложенные маршруты, где каждый компонент отвечает только за свой уровень. Родитель может предоставлять общий layout:

const rootRoute = new Route({
  path: '/',
  component: RootLayout,
  children: [
    new Route({ path: 'dashboard', component: Dashboard }),
    new Route({ path: 'settings', component: Settings }),
  ],
});
  • Родительский component может рендерить <Outlet /> — место для дочернего маршрута.
  • Такой подход облегчает создание модульного интерфейса, где layout, навигация и контент разделены по логике приложения.

Поддержка TypeScript

TanStack Router полностью типизирован. Параметры маршрута, query и результаты loader автоматически получают типы. Это снижает количество ошибок и повышает читаемость кода.

interface User {
  id: string;
  name: string;
}

new Route({
  path: '/users/:id',
  loader: async ({ params }): Promise<User> => {
    const response = await fetch(`/api/users/${params.id}`);
    return response.json();
  },
});

Типизация обеспечивает строгую проверку на этапе компиляции, делая приложение более надежным.


Итоговая структура интерфейса

TanStack Router позволяет объединить следующие элементы:

  • Маршруты и вложенность
  • Асинхронная загрузка данных
  • Обработка ошибок и состояния загрузки
  • Параметры пути и query
  • Типизация для TypeScript
  • Декларативная и программная навигация
  • Модульные layout-компоненты через <Outlet />

Эти возможности создают фундамент для построения сложных и масштабируемых веб-приложений с чистой и поддерживаемой архитектурой.