React Router предоставляет мощные механизмы работы с маршрутами и
компонентами, в том числе встроенную поддержку обработки ошибок на
уровне маршрутов. Хук useRouteError позволяет получать
информацию об ошибках, произошедших во время рендеринга маршрута или
загрузки данных. Его основная задача — предоставить доступ к объекту
ошибки в компоненте-обработчике ошибок (ErrorBoundary)
маршрута.
useRouteError импортируется из пакета
react-router-dom:
import { useRouteError } from "react-router-dom";
Он используется внутри компонента, который назначен свойством
errorElement маршрута:
import { useRouteError } from "react-router-dom";
function ErrorPage() {
const error = useRouteError();
console.error(error);
return (
<div>
<h1>Произошла ошибка</h1>
<p>{error.statusText || error.message}</p>
</div>
);
}
Для того чтобы useRouteError корректно работал,
необходимо определить маршрут с errorElement:
import { createBrowserRouter, RouterProvider } from "react-router-dom";
const router = createBrowserRouter([
{
path: "/",
element: <MainPage />,
errorElement: <ErrorPage />,
children: [
{
path: "profile/:id",
element: <ProfilePage />,
loader: async ({ params }) => {
const response = await fetch(`/api/users/${params.id}`);
if (!response.ok) {
throw new Response("Не удалось загрузить пользователя", { status: response.status });
}
return response.json();
},
},
],
},
]);
<RouterProvider router={router} />;
В этом примере, если загрузка данных в loader
завершается ошибкой, компонент ErrorPage автоматически
получит объект ошибки через useRouteError.
useRouteError возвращает объект, который может быть
экземпляром Error, Response или
пользовательского объекта. Основные поля, которые могут быть
полезны:
message — текст ошибки (если ошибка была выброшена как
Error).status — HTTP-статус (если ошибка представлена как
Response).statusText — описание статуса (для
Response).Пример проверки типа ошибки:
const error = useRouteError();
if (error instanceof Response) {
return <p>Ошибка загрузки данных: {error.status} {error.statusText}</p>;
} else if (error instanceof Error) {
return <p>Произошла ошибка: {error.message}</p>;
} else {
return <p>Неизвестная ошибка</p>;
}
useRouteError тесно связан с механизмом
loader маршрутов. Любая ошибка, выброшенная внутри
loader, автоматически передается в
errorElement. Это позволяет централизованно обрабатывать
ошибки загрузки данных без необходимости оборачивать каждый
fetch в try/catch.
Пример асинхронной обработки:
async function userLoader({ params }) {
try {
const response = await fetch(`/api/users/${params.id}`);
if (!response.ok) {
throw new Response("Пользователь не найден", { status: 404 });
}
return response.json();
} catch (err) {
throw new Error("Сбой сети");
}
}
Если произошла ошибка сети, ErrorPage получит экземпляр
Error. Если пользователь не найден, будет передан объект
Response.
React Router поддерживает вложенные маршруты, и
useRouteError возвращает ошибку именно текущего маршрута.
Ошибки дочернего маршрута не «просачиваются» в родительский, если у
родителя определён собственный errorElement. Это позволяет
строить точечную обработку ошибок для разных частей приложения.
Пример:
const router = createBrowserRouter([
{
path: "/",
element: <Layout />,
errorElement: <MainError />,
children: [
{
path: "dashboard",
element: <Dashboard />,
errorElement: <DashboardError />,
},
{
path: "settings",
element: <Settings />,
},
],
},
]);
В этом случае ошибка в маршруте /dashboard попадёт в
DashboardError, а ошибка в маршруте /settings
— в MainError.
useRouteError только внутри компонентов,
назначенных как errorElement. Вне этого контекста он вернёт
undefined.throw в
loader, чтобы ошибка автоматически передавалась в
errorElement.Error или Response)
для корректного отображения информации пользователю.Outlet для вложенных маршрутов,
сохраняя единообразную обработку ошибок в разных уровнях
приложения.useRouteError упрощает управление ошибками, позволяя
полностью отделить логику рендеринга данных от логики их обработки в
случае сбоев. Это делает приложение более устойчивым и упрощает
поддержку структуры маршрутов с комплексной загрузкой данных.