В TanStack Router ленивое (асинхронное) подключение компонентов и данных позволяет оптимизировать производительность приложения, загружая только необходимый код и данные по мере надобности. Однако при использовании ленивой загрузки необходимо учитывать возможность ошибок, связанных с динамическим импортом, сетевыми сбоями или некорректными данными. TanStack Router предоставляет гибкие механизмы для перехвата и обработки таких ошибок.
Ленивая загрузка компонентов в TanStack Router реализуется через
функцию lazy, которая принимает функцию динамического
импорта:
import { lazy } from '@tanstack/router';
const HomePage = lazy(() => import('./pages/HomePage'));
const ProfilePage = lazy(() => import('./pages/ProfilePage'));
Внутри маршрутизатора ленивые компоненты указываются как обычные компоненты:
const router = createRouter({
routes: [
{
path: '/',
component: HomePage,
},
{
path: '/profile',
component: ProfilePage,
},
],
});
При этом TanStack Router автоматически обрабатывает состояние загрузки компонента, но для обработки ошибок необходима дополнительная конфигурация.
errorElementКаждый маршрут в TanStack Router может содержать поле
errorElement, которое рендерится при возникновении ошибки в
маршруте, включая ошибки ленивой загрузки:
import ErrorPage from './pages/ErrorPage';
const router = createRouter({
routes: [
{
path: '/profile',
component: ProfilePage,
errorElement: <ErrorPage />,
},
],
});
В этом случае, если динамический импорт не удастся (например, файл
отсутствует или произошел сбой сети), TanStack Router отобразит
ErrorPage, передав объект ошибки в компонент.
useRouteError для получения ошибкиКомпонент, указанный в errorElement, может получить
информацию об ошибке с помощью хука useRouteError:
import { useRouteError } from '@tanstack/router';
function ErrorPage() {
const error = useRouteError();
return (
<div>
<h1>Произошла ошибка</h1>
<p>{error.message}</p>
</div>
);
}
useRouteError возвращает объект ошибки, который может
быть любым: от стандартного Error до пользовательских
объектов. Это позволяет выводить подробную информацию о проблеме и
реализовывать кастомные стратегии обработки.
SuspenseTanStack Router тесно интегрирован с React Suspense, что
позволяет обрабатывать состояние загрузки ленивых компонентов:
import { Suspense } from 'react';
const router = createRouter({
routes: [
{
path: '/profile',
component: (
<Suspense fallback={<div>Загрузка...</div>}>
<ProfilePage />
</Suspense>
),
errorElement: <ErrorPage />,
},
],
});
Поле fallback отображается до завершения загрузки
асинхронного компонента. Если же загрузка завершится ошибкой, будет
показан errorElement.
Помимо компонентов, TanStack Router поддерживает ленивую загрузку
данных через loader:
const profileLoader = async () => {
const response = await fetch('/api/profile');
if (!response.ok) throw new Error('Не удалось загрузить профиль');
return response.json();
};
const router = createRouter({
routes: [
{
path: '/profile',
component: ProfilePage,
loader: profileLoader,
errorElement: <ErrorPage />,
},
],
});
Если loader выбрасывает ошибку, маршрутизатор
автоматически передаст её в errorElement. В
ErrorPage можно вывести текст ошибки, статус HTTP или
предложить пользователю повторить загрузку.
TanStack Router поддерживает глобальную обработку ошибок через корневой маршрут. Например:
const rootRoute = {
path: '/',
component: <RootLayout />,
errorElement: <GlobalErrorPage />,
children: [
{ path: '/', component: HomePage },
{ path: '/profile', component: ProfilePage, loader: profileLoader },
],
};
const router = createRouter({ routes: [rootRoute] });
Любая ошибка в дочерних маршрутах будет перехвачена глобальным
errorElement, если локальные errorElement не
определены. Это упрощает централизованное логирование ошибок и создание
единообразного интерфейса уведомления пользователя.
errorElement для ленивых маршрутов и
асинхронных загрузчиков данных.useRouteError для получения подробной
информации об ошибке.Suspense и errorElement,
чтобы разделить состояние загрузки и ошибки.TanStack Router предоставляет полный инструментарий для безопасной и предсказуемой ленивой загрузки, позволяя управлять ошибками как на уровне отдельных маршрутов, так и на уровне всего приложения. Такой подход улучшает стабильность и UX, особенно в крупных приложениях с динамическими компонентами и асинхронными данными.