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 — вложенные маршруты для
построения сложных иерархий страниц.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 },
],
});
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.Типизация в 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, исключая ошибки доступа к
несуществующим свойствам.