TanStack Router предоставляет мощный механизм маршрутизации для приложений на JavaScript, позволяя управлять асинхронной загрузкой компонентов и данных. Одним из ключевых аспектов при работе с динамическими импортами является управление состояниями загрузки и ошибок. Для этого используется концепция fallback, которая позволяет отображать промежуточный контент, пока нужный чанк загружается.
В TanStack Router маршруты могут быть определены с использованием
функции loader или через динамический импорт
компонентов. Например:
import { createRouter, Route } from '@tanstack/router';
const Home = React.lazy(() => import('./pages/Home'));
const About = React.lazy(() => import('./pages/About'));
const router = createRouter({
routes: [
{
path: '/',
element: <Home />,
},
{
path: '/about',
element: <About />,
},
],
});
В этом примере компоненты Home и About
подгружаются лениво. Пока чанк не загрузился, React не отображает
компонент. Без fallback пользователь увидит пустой экран.
<Suspense> для fallbackДля отображения промежуточного состояния используется стандартный
механизм React — <Suspense>:
import React, { Suspense } from 'react';
function App() {
return (
<Suspense fallback={<div>Загрузка...</div>}>
<RouterProvider router={router} />
</Suspense>
);
}
Ключевые моменты:
fallback принимает JSX, который будет отображен, пока
загружается компонент.<Suspense> может быть применен как к отдельным
компонентам, так и к всему дереву маршрутов.TanStack Router позволяет задавать локальные fallback для отдельных маршрутов, что удобно, когда разные страницы имеют различное время загрузки:
const router = createRouter({
routes: [
{
path: '/profile',
element: (
<Suspense fallback={<div>Загрузка профиля...</div>}>
<Profile />
</Suspense>
),
},
{
path: '/settings',
element: (
<Suspense fallback={<div>Загрузка настроек...</div>}>
<Settings />
</Suspense>
),
},
],
});
Преимущество локальных fallback заключается в том, что пользователь получает конкретную информацию о том, какая часть приложения загружается, вместо общего индикатора загрузки для всего приложения.
Для динамических импортов возможны ошибки, например, из-за сетевых сбоев. TanStack Router поддерживает error boundaries, которые можно комбинировать с fallback:
function ErrorFallback({ error }) {
return <div>Произошла ошибка: {error.message}</div>;
}
const router = createRouter({
routes: [
{
path: '/dashboard',
element: (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<Suspense fallback={<div>Загрузка панели управления...</div>}>
<Dashboard />
</Suspense>
</ErrorBoundary>
),
},
],
});
Особенности:
ErrorBoundary перехватывает ошибки при загрузке
чанка.<Suspense> обеспечивает плавный UX:
сначала отображается fallback, затем либо компонент, либо сообщение об
ошибке.TanStack Router поддерживает стратегию prefetch и progressive loading, что улучшает UX:
import { Link } from '@tanstack/router';
function Navigation() {
return (
<>
<Link to="/profile" preload="intent">Профиль</Link>
<Link to="/settings" preload="intent">Настройки</Link>
</>
);
}
preload="intent" инициирует предварительную
загрузку чанка при наведении курсора.<Suspense> для плавной
анимации прогресса загрузки.Иногда требуется отображать fallback, зависящий от состояния загрузки данных:
function ProfileLoader() {
const { data, isLoading } = useProfileData();
if (isLoading) {
return <div>Загрузка данных профиля...</div>;
}
return <Profile data={data} />;
}
<Suspense> для полной
поддержки асинхронного контента на странице.<Suspense> с Error
Boundaries для надежного UX.Эта система позволяет создавать плавное взаимодействие с пользователем даже в сложных приложениях с большим количеством лениво загружаемых компонентов, обеспечивая управляемые fallback-элементы и обработку ошибок на уровне маршрутов.