Компонент Routes и Route

В библиотеке React Router компоненты Routes и Route используются для организации маршрутизации в приложении. Routes выступает контейнером для набора маршрутов, а Route описывает конкретный путь и компонент, который будет рендериться при совпадении URL.

import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}

Атрибуты компонента Route

  1. path – задаёт путь маршрута. Он может содержать параметры, например :id:

    <Route path="/users/:id" element={<UserProfile />} />

    В этом случае, если URL соответствует /users/123, компонент UserProfile сможет получить параметр id через хук useParams.

  2. element – компонент, который будет отрисован при совпадении пути. Значение обязательно передавать в виде JSX <Component />.

  3. index – указывает, что маршрут является индексным для родительского пути. Используется вместо указания конкретного path для корневого компонента внутри вложенных маршрутов:

    <Route path="dashboard">
      <Route index element={<DashboardHome />} />
      <Route path="stats" element={<Stats />} />
    </Route>
  4. children – можно вкладывать маршруты внутри других маршрутов для организации иерархической структуры.

Иерархия маршрутов

React Router поддерживает вложенные маршруты. Родительский Route может содержать дочерние маршруты, которые наследуют путь родителя:

<Routes>
  <Route path="/dashboard" element={<Dashboard />}>
    <Route path="analytics" element={<Analytics />} />
    <Route path="settings" element={<Settings />} />
  </Route>
</Routes>

В этом примере путь к Analytics будет /dashboard/analytics, а к Settings/dashboard/settings. Родительский компонент Dashboard может использовать <Outlet /> для отображения дочерних компонентов:

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

function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <Outlet />
    </div>
  );
}

Использование динамических параметров

Параметры пути позволяют создавать маршруты с переменными значениями:

<Route path="/products/:productId" element={<ProductDetail />} />

Компонент ProductDetail может извлекать параметр с помощью хука useParams:

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

function ProductDetail() {
  const { productId } = useParams();
  return <div>Детали продукта: {productId}</div>;
}

Обработка «не найдено» с помощью *

Маршрут с путём * позволяет отлавливать все неизвестные маршруты:

<Route path="*" element={<NotFound />} />

Это особенно полезно для отображения страницы 404, когда пользователь вводит URL, который не соответствует ни одному маршруту.

Навигация между маршрутами

Для перехода между маршрутами используется компонент <Link> или хук useNavigate:

import { Link, useNavigate } from "react-router-dom";

function Menu() {
  const navigate = useNavigate();
  
  return (
    <div>
      <Link to="/">Главная</Link>
      <Link to="/about">О нас</Link>
      <button onCl ick={() => navigate("/dashboard")}>Перейти в Dashboard</button>
    </div>
  );
}

Link создает навигацию без перезагрузки страницы, а useNavigate позволяет программно менять путь.

Отличия между Switch и Routes

В предыдущих версиях React Router использовался компонент Switch. В новых версиях он заменён на Routes, который:

  • Поддерживает вложенные маршруты через Outlet.
  • Обрабатывает совпадение пути с более точной логикой.
  • Требует явного использования атрибута element вместо component или render.

Примеры вложенных маршрутов с индексным маршрутом

<Routes>
  <Route path="app" element={<AppLayout />}>
    <Route index element={<HomePage />} />
    <Route path="profile" element={<Profile />} />
    <Route path="settings" element={<Settings />} />
  </Route>
</Routes>

Здесь HomePage рендерится при переходе на /app, а дочерние страницы доступны по /app/profile и /app/settings. Компонент AppLayout должен содержать <Outlet /> для отображения этих дочерних компонентов.

Практические советы

  • Всегда использовать <BrowserRouter> или <HashRouter> на верхнем уровне приложения.
  • Для маршрутов с динамическими параметрами проверять наличие параметров через useParams.
  • Для вложенных маршрутов обязательно использовать <Outlet /> в родительском компоненте.
  • Использовать маршрут * для отлова несуществующих путей и отображения страницы 404.

Этот набор правил и примеров позволяет строить сложные маршрутизируемые приложения на React с удобной структурой и управлением навигацией.