useRoutes для программного создания маршрутов

useRoutes — это хук библиотеки React Router, позволяющий программно создавать маршруты на основе конфигурации. Он особенно полезен при динамическом формировании маршрутов, когда их структура может зависеть от состояния приложения или данных с сервера.

import { useRoutes } from "react-router-dom";

const routes = [
  { path: "/", element: <Home /> },
  { path: "about", element: <About /> },
  { path: "dashboard", element: <Dashboard /> },
];

function App() {
  const element = useRoutes(routes);
  return element;
}

Здесь routes — массив объектов, где каждый объект описывает отдельный маршрут. Свойство path задаёт путь маршрута, а element — React-компонент, который будет отрендерен при совпадении пути.


Структура конфигурации маршрутов

Каждый объект маршрута может содержать следующие ключи:

  • path: строка, определяющая путь маршрута. Поддерживаются динамические сегменты (:id) и вложенные пути.
  • element: компонент React, который будет отрендерен.
  • children: массив объектов маршрутов для вложенной маршрутизации.
  • index: булевое значение для создания индексного маршрута внутри родителя.
  • errorElement: компонент для отображения ошибок маршрута.

Пример вложенной маршрутизации:

const routes = [
  {
    path: "/dashboard",
    element: <DashboardLayout />,
    children: [
      { index: true, element: <DashboardHome /> },
      { path: "settings", element: <Settings /> },
      { path: "reports", element: <Reports /> },
    ],
  },
];

В этом примере при переходе на /dashboard отобразится DashboardHome. Для /dashboard/settings и /dashboard/reports будут свои компоненты. Использование index: true обозначает маршрут по умолчанию для родителя.


Динамические сегменты и параметры

React Router поддерживает динамические сегменты пути через двоеточие (:). Для извлечения параметров используется хук useParams.

const routes = [
  { path: "users/:userId", element: <UserProfile /> },
];

function UserProfile() {
  const { userId } = useParams();
  return <div>Профиль пользователя: {userId}</div>;
}

Параметр userId автоматически захватывается из URL и становится доступным внутри компонента.


Использование useRoutes с условной логикой

Маршруты можно создавать динамически в зависимости от состояния приложения, прав пользователя или конфигурации, полученной с сервера.

function App({ isAdmin }) {
  const routes = [
    { path: "/", element: <Home /> },
    { path: "login", element: <Login /> },
    isAdmin && { path: "admin", element: <AdminPanel /> },
  ].filter(Boolean);

  const element = useRoutes(routes);
  return element;
}

Использование filter(Boolean) позволяет исключить false значения из массива маршрутов, что удобно для условной маршрутизации.


Обработка ошибок маршрутов

Каждый маршрут может иметь собственный компонент для отображения ошибок через свойство errorElement.

const routes = [
  {
    path: "/",
    element: <Home />,
    errorElement: <NotFound />,
  },
  { path: "*", element: <NotFound /> },
];

Звёздочка * обозначает маршрут по умолчанию для всех несуществующих путей. Вложенные маршруты могут иметь собственные обработчики ошибок, что позволяет точно контролировать отображение ошибок.


Индексные маршруты

Индексный маршрут используется для рендеринга компонента по умолчанию в рамках родительского маршрута. Он задаётся через index: true без указания path.

const routes = [
  {
    path: "dashboard",
    element: <DashboardLayout />,
    children: [
      { index: true, element: <DashboardHome /> },
      { path: "analytics", element: <Analytics /> },
    ],
  },
];

При переходе на /dashboard рендерится DashboardHome. При переходе на /dashboard/analyticsAnalytics.


Lazy загрузка компонентов с useRoutes

React Router поддерживает ленивую загрузку компонентов через React.lazy и Suspense. Это особенно полезно для больших приложений с множеством маршрутов.

import { Suspense, lazy } from "react";

const Home = lazy(() => import("./Home"));
const About = lazy(() => import("./About"));

const routes = [
  { path: "/", element: <Home /> },
  { path: "about", element: <About /> },
];

function App() {
  const element = useRoutes(routes);
  return <Suspense fallback={<div>Загрузка...</div>}>{element}</Suspense>;
}

Использование Suspense гарантирует отображение загрузочного состояния, пока компонент подгружается динамически.


Редиректы и Navigate

Для программного перенаправления внутри маршрутов используется компонент Navigate.

const routes = [
  { path: "/", element: <Home /> },
  { path: "old-path", element: <Navigate to="/new-path" replace /> },
];

Свойство replace предотвращает создание лишней записи в истории браузера.


Итоговые рекомендации по useRoutes

  • Использовать useRoutes для динамической и вложенной маршрутизации.
  • Применять индексные маршруты для рендеринга компонентов по умолчанию.
  • Выделять обработку ошибок через errorElement.
  • Поддерживать ленивую загрузку компонентов для оптимизации производительности.
  • Для динамических маршрутов использовать параметры и useParams.

useRoutes позволяет строить сложные структуры маршрутов в React, упрощая управление логикой отображения компонентов в зависимости от URL.