TanStack Router представляет собой современный подход к маршрутизации в приложениях на JavaScript и TypeScript. В отличие от классических роутеров, таких как React Router, он строится вокруг явного описания маршрутов, статических и динамических сегментов, а также первоклассной поддержки асинхронного получения данных.
Ключевые особенности:
loader, который выполняется до рендеринга компонента.Маршрут в TanStack Router описывается объектом, который включает следующие ключевые поля:
const route = {
path: '/users/:userId',
component: UserPage,
loader: async ({ params }) => {
return fetchUser(params.userId);
},
children: [
{
path: 'posts',
component: UserPosts,
loader: async ({ params }) => fetchPosts(params.userId),
}
],
};
Объяснение ключевых элементов:
path: путь маршрута с поддержкой динамических сегментов
(:userId).component: компонент, который рендерится для данного
маршрута.loader: асинхронная функция, вызываемая до рендеринга.
Возвращаемые данные становятся доступными через хук
useLoaderData.children: вложенные маршруты, позволяющие строить
иерархическую структуру.React Router использует JSX-компоненты и
для определения маршрутов, в то время как
TanStack Router требует объектного описания маршрутов.
Основные шаги при миграции:
// React Router
} />
} />
// TanStack Router
const routes = [
{
path: '/users/:id',
component: UserPage,
children: [
{ path: 'posts', component: UserPosts }
]
}
];
useParams на useParams
TanStack Router: В TanStack Router доступ к параметрам маршрута
осуществляется через встроенный хук:import { useParams } from '@tanstack/router';
const params = useParams();
console.log(params.id);
loader вместо
useEffect: Loader позволяет заранее загружать
данные до рендеринга компонента, что упрощает работу с асинхронными
запросами и устраняет лишние состояния загрузки.const userRoute = {
path: '/users/:id',
component: UserPage,
loader: async ({ params }) => {
return fetch(`/api/users/${params.id}`).then(res => res.json());
}
};
В отличие от многих старых роутеров, TanStack Router нативно поддерживает глубокую вложенность без необходимости ручного построения путей. Каждый дочерний маршрут автоматически наследует путь родителя:
const routes = [
{
path: '/dashboard',
component: DashboardLayout,
children: [
{
path: 'analytics',
component: AnalyticsPage,
},
{
path: 'settings',
component: SettingsPage,
}
]
}
];
Доступ к маршруту dashboard/analytics выполняется
автоматически через объектную структуру, и нет необходимости вручную
конкатенировать пути.
Вместо и navigate React
Router, TanStack Router предоставляет:
useNavigate для программной
навигации:const navigate = useNavigate();
navigate({ to: '/users/42' });
Link компонент для декларативной
навигации с типизацией:Профиль пользователя
useIsPending:const isPending = useIsPending();
if (isPending) {
return ;
}
TanStack Router позволяет задавать маршрутные обработчики ошибок:
const errorRoute = {
path: '*',
component: NotFoundPage,
};
const protectedRoute = {
path: '/admin',
component: AdminPage,
loader: async () => {
const isAdmin = await checkAdmin();
if (!isAdmin) throw new Response('Unauthorized', { status: 401 });
},
errorComponent: UnauthorizedPage,
};
В случае ошибки loader можно отобразить специальный
компонент без необходимости использования глобальных try/catch блоков в
компонентах.
TanStack Router полностью интегрирован с TypeScript:
loader.Пример типизированного маршрута:
interface UserParams {
userId: string;
}
const userRoute = new Route({
path: '/users/:userId',
component: UserPage,
loader: async ({ params }) => fetchUser(params.userId),
});
Такой подход обеспечивает полную безопасность при переходах и работе с данными, чего сложно достичь в классических роутерах.