В TanStack Router управление состоянием загрузки (loading state) является одним из ключевых аспектов построения отзывчивых и предсказуемых интерфейсов. Библиотека предоставляет встроенные механизмы для отслеживания загрузки данных на уровне маршрутов и компонентов, что позволяет создавать сложные асинхронные сценарии без лишнего кода.
Каждый маршрут в TanStack Router может иметь функцию
loader, которая отвечает за асинхронное получение данных
перед рендерингом компонента. Функция loader возвращает
промис, а TanStack Router автоматически отслеживает состояние этого
промиса.
import { createRouter, createRouteConfig } from '@tanstack/router';
const rootRoute = createRouteConfig({
path: '/',
component: RootComponent,
});
const userRoute = rootRoute.createRoute({
path: 'user/:userId',
component: UserComponent,
loader: async ({ params }) => {
const response = await fetch(`/api/users/${params.userId}`);
if (!response.ok) {
throw new Error('Failed to load user');
}
return response.json();
},
});
const router = createRouter({ routeConfig: rootRoute });
В этом примере loader маршрута user/:userId
выполняет асинхронный запрос к API. Пока промис не завершён, маршрут
находится в состоянии загрузки.
useIsLoading и useMatchДля отслеживания состояния загрузки компонентов и маршрутов TanStack
Router предоставляет хуки useIsLoading и
useMatch.
useIsLoading позволяет проверить,
выполняется ли в данный момент загрузка данных для конкретного
маршрута.useMatch позволяет получить состояние
конкретного маршрута и информацию о его loader.import { useIsLoading, useMatch } from '@tanstack/router';
function LoadingIndicator() {
const isLoading = useIsLoading({ from: rootRoute });
return isLoading ? <div>Загрузка...</div> : null;
}
function UserComponent() {
const match = useMatch(userRoute);
const user = match.data;
return (
<div>
{match.isLoading ? 'Загрузка данных пользователя...' : `Имя: ${user.name}`}
</div>
);
}
useIsLoading автоматически отслеживает все активные
loader маршрутов, указанных в параметре from.
useMatch предоставляет объект с полями:
data — данные, возвращённые loader;isLoading — булевое значение состояния загрузки;error — объект ошибки, если промис loader
завершился с ошибкой.TanStack Router поддерживает как глобальные, так и локальные индикаторы загрузки.
useIsLoading без конкретного
from:function GlobalLoading() {
const isLoading = useIsLoading();
return isLoading ? <div className="global-spinner">Загрузка приложения...</div> : null;
}
function UserDetails() {
const match = useMatch(userRoute);
if (match.isLoading) return <div>Загрузка информации о пользователе...</div>;
return <div>{match.data.name}</div>;
}
Помимо loader, TanStack Router поддерживает асинхронные
действия (action) для маршрутов. Эти действия также
интегрируются с системой отслеживания состояния загрузки, что позволяет
синхронизировать интерфейс с выполнением операций, например, отправкой
формы.
const editUserRoute = userRoute.createRoute({
path: 'edit',
component: EditUser,
action: async ({ params, formData }) => {
const response = await fetch(`/api/users/${params.userId}`, {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Ошибка при обновлении пользователя');
}
return response.json();
},
});
Компоненты, использующие useMatch или
useIsLoading, автоматически реагируют на состояние загрузки
action. Таким образом, можно показывать спиннеры,
блокировать кнопки или информировать пользователя о процессе выполнения
асинхронной операции.
isLoading для условного рендеринга
skeleton-компонентов.from в useIsLoading позволяет отслеживать
загрузку только для конкретных маршрутов, что снижает количество
ненужных обновлений UI.loader и
errorBoundary позволяет корректно реагировать на ошибки
загрузки, не ломая структуру приложения.const dashboardRoute = rootRoute.createRoute({
path: 'dashboard',
component: Dashboard,
loader: async () => {
const [stats, notifications] = await Promise.all([
fetch('/api/stats').then(res => res.json()),
fetch('/api/notifications').then(res => res.json()),
]);
return { stats, notifications };
},
});
function App() {
return (
<>
<GlobalLoading />
<RouterProvider router={router} />
</>
);
}
Сочетание этих методов обеспечивает гибкую систему управления состоянием загрузки для сложных SPA-приложений. TanStack Router обеспечивает прозрачную интеграцию асинхронных процессов с интерфейсом, позволяя строить предсказуемый UX без лишней логики управления промисами.