Что такое TanStack Router

TanStack Router — это современная библиотека маршрутизации для приложений на JavaScript и TypeScript, ориентированная на декларативный подход и гибкое управление состоянием маршрутов. Она позволяет создавать сложные клиентские маршруты с поддержкой вложенных страниц, ленивой загрузки компонентов, асинхронных данных и типизации, что делает её особенно удобной для масштабных проектов на React.


Декларативная структура маршрутов

В TanStack Router маршруты описываются через объектную структуру, что делает конфигурацию предельно наглядной. Каждый маршрут имеет набор ключевых свойств: path, component, loader, children.

Пример базового маршрута:

import { createRouter, RouterProvider } from '@tanstack/router';
import Home from './pages/Home';
import About from './pages/About';

const router = createRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
  ],
});

function App() {
  return ;
}
  • path — путь маршрута, может содержать динамические параметры (/user/:id).
  • component — компонент, который отображается при совпадении маршрута.
  • children — вложенные маршруты для построения сложных иерархий страниц.

Вложенные маршруты и outlet

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

Пример вложенного маршрута:

const router = createRouter({
  routes: [
    {
      path: '/dashboard',
      component: DashboardLayout,
      children: [
        { path: 'analytics', component: AnalyticsPage },
        { path: 'settings', component: SettingsPage },
      ],
    },
  ],
});

Внутри DashboardLayout:

function DashboardLayout() {
  return (
    
); }

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


Динамические параметры и типизация

Маршруты с параметрами позволяют динамически подставлять значения в URL. TanStack Router интегрирован с TypeScript, что обеспечивает строгую типизацию параметров маршрута и данных.

Пример динамического маршрута:

const router = createRouter({
  routes: [
    {
      path: '/user/:userId',
      component: UserProfile,
      loader: async ({ params }) => {
        const response = await fetch(`/api/users/${params.userId}`);
        return response.json();
      },
    },
  ],
});
  • params — объект с динамическими параметрами URL.
  • loader — функция для предварительной загрузки данных до рендеринга компонента.

Асинхронная загрузка данных

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

function UserProfile({ loaderData }) {
  if (!loaderData) return 
Загрузка...
; return
Имя пользователя: {loaderData.name}
; }

Преимущества:

  • Уменьшение количества дополнительных состояний в компоненте.
  • Централизация логики загрузки данных на уровне маршрута.
  • Поддержка типов для данных, что исключает ошибки доступа к свойствам.

Навигация и управление состоянием маршрутов

TanStack Router предоставляет декларативные и программные методы навигации. Ключевой инструмент — хук useRouter.

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

function NavigationButton() {
  const router = useRouter();
  return (
    
  );
}

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

  • navigate(path, options) — программная навигация с поддержкой состояния, замены истории и переходов по ссылкам.
  • router.state — позволяет отслеживать текущий маршрут, параметры и данные.

Поддержка ленивой загрузки компонентов

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

const DashboardPage = React.lazy(() => import('./pages/DashboardPage'));

const router = createRouter({
  routes: [
    { path: '/dashboard', component: DashboardPage },
  ],
});
  • Компонент загружается только при переходе на маршрут.
  • Снижает первоначальный размер бандла.
  • Совместимо с React Suspense для отображения индикаторов загрузки.

Защищенные маршруты и авторизация

Маршруты можно защищать, используя loader для проверки состояния пользователя или токена:

const ProtectedRoute = {
  path: '/admin',
  loader: async () => {
    const user = await fetch('/api/me').then(r => r.json());
    if (!user.isAdmin) throw new Error('Нет доступа');
    return user;
  },
  component: AdminDashboard,
};
  • Если проверка не проходит, можно перенаправлять пользователя или показывать ошибку.
  • Позволяет централизовать логику авторизации на уровне маршрута.

Поддержка маршрутов с состоянием

TanStack Router позволяет передавать состояние при переходе:

router.navigate('/profile', { state: { from: '/dashboard' } });
  • Это удобно для реализации функционала возврата к предыдущему месту.
  • Состояние доступно через объект location.state.

Интеграция с TypeScript

Типизация в TanStack Router охватывает:

  • Параметры маршрута (params)
  • Данные, возвращаемые loader (loaderData)
  • Навигацию (navigate и router.state)

Пример:

interface UserLoaderData {
  name: string;
  email: string;
}

const router = createRouter({
  routes: [
    {
      path: '/user/:id',
      component: UserProfile,
      loader: async ({ params }): Promise => {
        const res = await fetch(`/api/users/${params.id}`);
        return res.json();
      },
    },
  ],
});

TypeScript гарантирует, что UserProfile получит объект с полями name и email, исключая ошибки доступа к несуществующим свойствам.