В TanStack Router loader — это функция, которая выполняется перед рендерингом маршрута и отвечает за подготовку данных, необходимых для компонента. Одним из ключевых применений loader’ов является проверка авторизации пользователя и управление доступом к защищённым маршрутам.
Асинхронная природа loader’ов Loader может быть асинхронной функцией, что позволяет выполнять запросы к серверу или проверять токены аутентификации перед отображением компонента. Асинхронность важна для случаев, когда авторизация требует валидации JWT, проверки сессии или загрузки данных пользователя.
Доступ к объекту context и
params Loader получает объект
context, содержащий глобальные данные приложения, и
params, включающие параметры маршрута. Проверка авторизации
часто строится на наличии токена в контексте или на данных из
глобального состояния, например, Redux, Zustand или React
Context.
import { createRouter } from '@tanstack/router';
import { redirect } from '@tanstack/router';
const router = createRouter({
routes: [
{
path: '/dashboard',
component: Dashboard,
loader: async ({ context }) => {
if (!context.user?.isAuthenticated) {
throw redirect('/login');
}
return null;
},
},
],
});
В этом примере loader проверяет, авторизован ли пользователь, и при отсутствии авторизации выполняет перенаправление на страницу входа.
Для сложных приложений часто требуется проверка роли пользователя:
loader: async ({ context }) => {
const user = context.user;
if (!user) throw redirect('/login');
if (!user.roles.includes('admin')) throw redirect('/unauthorized');
return user;
}
В данном случае loader проверяет не только факт авторизации, но и наличие определённой роли, что позволяет ограничить доступ к административным страницам.
Чтобы избежать дублирования кода проверки авторизации на каждом
маршруте, можно создать универсальную функцию
requireAuth:
function requireAuth(user, redirectTo = '/login') {
if (!user?.isAuthenticated) {
throw redirect(redirectTo);
}
return user;
}
// Использование
loader: ({ context }) => requireAuth(context.user)
Такой подход улучшает читаемость и поддерживаемость маршрутов.
TanStack Router позволяет ловить ошибки loader’ов через
ErrorBoundary. Это особенно полезно, если проверка
авторизации может возвращать кастомные ошибки:
{
path: '/dashboard',
component: Dashboard,
loader: ({ context }) => requireAuth(context.user),
errorComponent: AuthErrorPage,
}
Если loader выбрасывает исключение, AuthErrorPage
получает объект ошибки и может отображать сообщение пользователю.
Часто проверка авторизации требует запроса к API для проверки действительности токена:
loader: async ({ context }) => {
const token = context.user?.token;
const response = await fetch('/api/verify-token', {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) throw redirect('/login');
const userData = await response.json();
return userData;
}
В этом примере loader гарантирует, что маршрут будет доступен только после успешной валидации токена на сервере.
Loader может возвращать объект с данными пользователя, которые затем становятся доступными компоненту маршрута:
loader: async ({ context }) => {
const user = requireAuth(context.user);
return { user };
}
// В компоненте
function Dashboard({ loaderData }) {
return <div>Добро пожаловать, {loaderData.user.name}</div>;
}
Это позволяет компонентам оставаться чистыми и сосредоточенными только на отображении данных.
ErrorBoundary: это упрощает вывод сообщений и
управление доступом.Таким образом, loader’ы TanStack Router предоставляют мощный инструмент для управления доступом, позволяя реализовать гибкую и безопасную систему авторизации на уровне маршрутов.