В TanStack Router обработка ошибок и восстановление после них
строится вокруг концепции error boundaries. Ошибки
могут возникать как на уровне загрузки данных (loader),
действий (action), так и в компонентах маршрутов. Понимание
того, как библиотека структурирует обработку ошибок, позволяет создавать
устойчивые приложения и предотвращать падение всей страницы при
локальных сбоях.
Каждый маршрут может иметь собственный errorElement. Это
компонент, который будет рендериться в случае ошибки в этом маршруте или
его потомках:
import { Router, Route } from '@tanstack/router'
const ErrorPage = ({ error }) => (
<div>
<h1>Произошла ошибка</h1>
<pre>{error.message}</pre>
</div>
)
const router = new Router({
routeTree: Route({
path: '/',
component: HomePage,
errorElement: ErrorPage,
children: [
Route({
path: 'profile',
component: ProfilePage,
}),
],
}),
})
Ключевой момент: ошибка в дочернем маршруте пробрасывается
вверх к ближайшему errorElement, а не ломает весь
роутер.
TanStack Router активно использует загрузчики данных и действия.
Любая ошибка в этих функциях автоматически прокидывается в
соответствующий errorElement.
const profileLoader = async () => {
const response = await fetch('/api/profile')
if (!response.ok) {
throw new Error('Не удалось загрузить профиль')
}
return response.json()
}
const profileRoute = Route({
path: '/profile',
component: ProfilePage,
loader: profileLoader,
errorElement: ProfileError,
})
Важные аспекты:
loader не вызывает повторного рендеринга
компонента маршрута. Вместо этого рендерится
errorElement.action (например, при отправке формы) ведет
себя аналогично — можно показывать локальные уведомления об ошибке, не
ломая страницу.В TanStack Router можно вернуть приложение в стабильное состояние после ошибки без полной перезагрузки. Для этого применяются несколько подходов:
useResetErrorBoundary
Хук позволяет программно сбросить состояние ошибки и заново попытаться
загрузить маршрут:import { useResetErrorBoundary } from '@tanstack/router'
function ErrorPage({ error }) {
const reset = useResetErrorBoundary()
return (
<div>
<p>Произошла ошибка: {error.message}</p>
<button onCl ick={reset}>Попробовать снова</button>
</div>
)
}
Автоматическое восстановление после изменения
пути Перемещение пользователя на другой маршрут автоматически
сбрасывает ошибку, что предотвращает зависание
errorElement.
Комбинация с Suspense и загрузкой данных Можно
объединять errorElement с <Suspense> для
асинхронного рендеринга компонентов, создавая плавное восстановление
после ошибок загрузки:
<Suspense fallback={<Loading />}>
<RouteComponent />
</Suspense>
Если загрузка завершилась ошибкой, сработает ближайший
errorElement.
Даже при использовании loader и action
иногда требуется перехватывать ошибки внутри
компонентов. Для этого TanStack Router позволяет комбинировать
стандартные React error boundaries с маршрутизатором:
class ComponentBoundary extends React.Component {
state = { hasError: false, error: null }
static getDerivedStateFromError(error) {
return { hasError: true, error }
}
render() {
if (this.state.hasError) {
return <div>Ошибка в компоненте: {this.state.error.message}</div>
}
return this.props.children
}
}
<Route path="/settings" component={() => (
<ComponentBoundary>
<SettingsPage />
</ComponentBoundary>
)} />
Этот подход полезен для локальных ошибок, которые не связаны с загрузкой данных маршрута.
errorElement, чтобы пользователь понимал, что
произошло.useResetErrorBoundary или изменение
маршрута для восстановления без полной перезагрузки страницы.loader, action или
компоненте.errorElement.errorElement рендерится, предотвращая падение всего
приложения.useResetErrorBoundary или переход на другой маршрут.loader.Эта архитектура обеспечивает гибкое, модульное и безопасное управление ошибками, сохраняя стабильность приложения и улучшая пользовательский опыт.