Гид по технологиям

Маршрутизация в React с React Router v6

5 min read Frontend Обновлено 02 Jan 2026
Маршрутизация в React с React Router v6
Маршрутизация в React с React Router v6

Экран ноутбука с кодом React и логотипом

TL;DR

React Router v6 — современная библиотека для маршрутизации в React: она упрощает вложенные маршруты, автоматически ранжирует совпадения и добавляет удобные хуки для навигации и состояния. Для простых приложений достаточно BrowserRouter и Routes/Route. Для централизованной конфигурации и расширенных сценариев используйте createBrowserRouter + RouterProvider и data API (v6.4+). В статье — практические примеры, советы по миграции, сценарии защиты маршрутов, чек-листы и краткий глоссарий.

Что такое React Router v6

React Router — библиотека для управления переходами в приложениях React. Версия 6 переработала алгоритм сопоставления маршрутов, добавила поддержку относительных маршрутов и новые API (хуки и провайдеры), которые делают конфигурацию яснее и безопаснее. Ключевая идея: маршруты — это дерево, которое мапится на дерево компонентов.

Начало работы

Создайте проект React (Create React App или Vite). Установите пакет:

npm install react-router-dom

Ниже — пошаговые примеры конфигурации и полезные паттерны.

Обёртывание приложения BrowserRouter

Чтобы компоненты получили доступ к контексту маршрутизации, оберните приложение в BrowserRouter (обычно в index.jsx или main.jsx):

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import { BrowserRouter as Router } from 'react-router-dom'

ReactDOM.createRoot(document.getElementById('root')).render(
  
    
      
    
  
)

BrowserRouter подходит для большинства приложений, где маршрутизация управляется на клиенте и нужен HTML5 history API.

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

Routes — замена Switch из v5. Она автоматически ранжирует маршруты и поддерживает относительные и вложенные маршруты.

Пример App.jsx:

import './App.css'
import { Routes, Route } from 'react-router-dom'
import Dashboard from './pages/Dashboard'
import About from './pages/About'

function App() {
  return (
    <>
      
        } />
        } />
      
    
  )
}

export default App

Обратите внимание на свойство element — оно принимает JSX-элемент, поэтому вы можете передавать пропсы и оборачивать компонент в провайдеры.

Использование createBrowserRouter и RouterProvider

Если вы предпочитаете централизованную конфигурацию маршрутов (массив объектов), используйте createBrowserRouter и RouterProvider. Это полезно при большом количестве маршрутов, SSR-подходах или когда нужно декларативно задавать loaders/errorElement/actions.

import React from 'react'
import ReactDOM from 'react-dom/client'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import App from './App.jsx'
import Dashboard from './pages/Dashboard'
import About from './pages/About'

const router = createBrowserRouter([
  { path: '/', element:  },
  { path: '/dashboard', element:  },
  { path: '/about', element:  },
])

ReactDOM.createRoot(document.getElementById('root')).render(
  
    
  
)

RouterProvider передаёт контекст маршрутизатора всем компонентам — аналога BrowserRouter не требуется в этом сценарии.

Важно: начиная с React Router v6.4 появился data API (loaders, actions, errorElement) — оно расширяет createBrowserRouter. Если ваш проект использует загрузку данных на уровне маршрутов, изучите соответствующие примеры в документации.

Маршрут «Страница не найдена» (404)

Используйте wildcard path “*” в Routes или в массиве createBrowserRouter для обработки несопадающих URL:

// с Route
} />

// с createBrowserRouter
{ path: '*', element:  }

Создайте компонент NotFound.jsx и стилизуйте его по дизайну приложения.

Программная навигация: useNavigate и useNavigation

useNavigate — хук для программной навигации (редирект по клику, после сабмита и т. п.).

import { useNavigate } from 'react-router-dom'

function About() {
  const navigate = useNavigate()

  const handleButtonClick = () => {
    navigate('/')
  }

  return (
    <>
      {/* Остальная разметка */}
      
    
  )
}

export default About

useNavigation возвращает текущее состояние навигации (например, “loading” или “submitting”) и полезен для отображения индикаторов загрузки:

import { useNavigation } from 'react-router-dom'

function SubmitButton() {
  const navigation = useNavigation()

  const buttonText =
    navigation.state === 'submitting'
      ? 'Сохранение...'
      : navigation.state === 'loading'
        ? 'Загрузка...'
        : 'Отправить'

  return 
}

Используйте оба хука вместе: useNavigate для перехода, useNavigation для показа прогресса.

Хук useRoutes

useRoutes позволяет описывать маршруты в виде массива объектов непосредственно в компоненте и возвращает результат сопоставления:

import { useRoutes } from 'react-router-dom'
import Dashboard from './Dashboard'
import About from './About'

const routes = [
  { path: '/', element:  },
  { path: '/about', element:  },
]

function App() {
  const routeResult = useRoutes(routes)
  return routeResult
}

export default App

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

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

Маршруты в v6 устроены как дерево: родительский маршрут рендерит Outlet, а дочерние рендерятся внутри него.

Пример вложения:

import { Outlet } from 'react-router-dom'

function DashboardLayout() {
  return (
    
Управление
) } // Конфигурация { path: '/dashboard', element: , children: [ { index: true, element: }, { path: 'settings', element: }, ]}

index: true обозначает маршрут по умолчанию для родителя.

Параметры маршрута и query-параметры

Параметры пути доступны через useParams:

import { useParams } from 'react-router-dom'

function User() {
  const { id } = useParams()
  return 
Пользователь {id}
}

Query-параметры не парсятся автоматически — используйте URLSearchParams вместе с useLocation:

import { useLocation } from 'react-router-dom'

function Search() {
  const { search } = useLocation()
  const params = new URLSearchParams(search)
  const q = params.get('q')
  return 
Результаты для: {q}
}

Защита маршрутов (Protected Routes)

Один из распространённых паттернов — защищённый маршрут, который проверяет авторизацию и редиректит на страницу логина:

import { Navigate, Outlet } from 'react-router-dom'

function RequireAuth({ isAuthenticated }) {
  if (!isAuthenticated) {
    return 
  }
  return 
}

// Конфигурация
{ path: '/app', element: , children: [
  { path: 'profile', element:  },
]}

Этот шаблон прост и совместим с маршрутизаторами как BrowserRouter, так и createBrowserRouter.

Ленивый импорт компонентов и Suspense

Для уменьшения размера бандла используйте React.lazy и Suspense:

import React, { Suspense, lazy } from 'react'
const Dashboard = lazy(() => import('./pages/Dashboard'))

function App() {
  return (
    Загрузка...
}> } /> ) }

Если вы используете data API (v6.4+), комбинируйте loaders с ленивым рендером для оптимальной UX.

Data API (loaders, actions, errorElement)

В версиях React Router v6.4+ появился набор инструментов для загрузки данных и обработки ошибок на уровне маршрутов (loaders, actions, errorElement). Они удобны для серверных запросов, форм и декларативной обработки ошибок. Изучите документацию перед внедрением — это мощный инструмент, меняющий архитектуру работы с данными.

Модель мышления: маршруты как дерево

Ментальная модель: представьте маршруты как дерево папок в файловой системе. Родитель определяет общий shell (навигация, сайдбар), дочерние — содержимое. Outlet — место для рендера дочерних элементов.

Когда React Router не подходит (контрпримеры)

  • Простая одностраничная страница с несколькими компонентами — можно обойтись без библиотеки.
  • Если у вас серверная маршрутизация (традиционный серверный рендеринг), может быть проще использовать фреймворк с собственной маршрутизацией (Next.js, Remix).
  • Для микрофронтендов с отдельными приложениями иногда удобнее иметь минимальные маршрутизаторы, чтобы не объединять глобальный контекст.

Практическая методология миграции с v5 на v6

  1. Обновите зависимости и запустите сборку.
  2. Замените Switch на Routes и компоненты Route (элемент — JSX).
  3. Проверьте вложенные маршруты: в v6 нужны Outlet и index-маршруты вместо exact.
  4. Замените useHistory на useNavigate.
  5. Тестируйте protected routes и редиректы (Navigate).

Чек-лист перед релизом (роль: разработчик)

  • Все маршруты корректно отображаются при прямом вводе URL
  • Нет конфликтующих путей (динамические и статические)
  • 404-страница настроена
  • Ленивая подгрузка критичных страниц работает
  • Protected routes корректно редиректят
  • Формы используют action/loader (если применимо)

Критерии приёмки

  • Навигация работает без перезагрузки страницы.
  • URL изменяется корректно при переходах.
  • При недоступном ресурсе отображается NotFound.
  • Защищённые страницы доступны только авторизованным пользователям.

Справочник — 1‑строчный глоссарий

  • BrowserRouter: провайдер, использующий history API.
  • Routes/Route: декларация совпадений URL → элемент.
  • RouterProvider: провайдер для createBrowserRouter.
  • useNavigate: программный переход.
  • useNavigation: информация о текущем переходе.
  • Outlet: место для рендера дочерних маршрутов.
  • loader/action: загрузка/обработка данных на уровне маршрута (v6.4+).

Решающее дерево выбора API (Mermaid)

flowchart TD
  A[Нужна централизованная конфигурация?] -->|Да| B[createBrowserRouter + RouterProvider]
  A -->|Нет| C[BrowserRouter + Routes]
  B --> D{Нужны loaders/actions/errorElement?}
  D -->|Да| E[Использовать data API 'v6.4+']
  D -->|Нет| F[Обычная конфигурация маршрутов]
  C --> G{Должны ли маршруты динамически меняться?}
  G -->|Да| H[useRoutes внутри компонента]
  G -->|Нет| F

(Для визуализации убедитесь, что ваш рендерер поддерживает Mermaid.)

Шаблонный код: Protected Route Snippet

import { Navigate, Outlet } from 'react-router-dom'

export function ProtectedRoute({ isAuthed, redirectTo = '/login' }) {
  return isAuthed ?  : 
}

Советы по производительности и безопасности

  • Минимизируйте количество одновременно загружаемых маршрутов через ленивую загрузку.
  • Не храните секреты в URL.
  • Для больших приложений разбивайте маршруты по фичам и используйте code-splitting.

Локальные особенности и миграционные хитрости

  • В проектах с TypeScript обязательно добавьте типы для loader/action.
  • При миграции следите за использованием exact и component — в v6 их нет.
  • Проверьте серверную настройку: при прямом переходе на URL сервер должен отдавать index.html (SPA).

Резюме

React Router v6 делает маршрутизацию яснее и мощнее: современный синтаксис, автоматическое ранжирование, удобные хуки и расширяемый data API. Для небольших приложений достаточно BrowserRouter + Routes, а для сложных — createBrowserRouter с loaders/actions и RouterProvider. При миграции обратите внимание на замену Switch → Routes, useHistory → useNavigate и на работу вложенных роутов через Outlet.

Важно: выбирайте подходящий API под архитектуру приложения, тестируйте прямые переходы по URL и настройте поведение 404/Protected-Route заранее.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Создать пошаговое руководство с Steps Recorder
Руководства

Создать пошаговое руководство с Steps Recorder

Ромбовидное наследование в C++ и как его решать
C++

Ромбовидное наследование в C++ и как его решать

Удвоить скорость прокрутки в TikTok
Руководство

Удвоить скорость прокрутки в TikTok

Установка Discord на Linux — пошагово
Linux

Установка Discord на Linux — пошагово

Как восстановить черновики TikTok
Социальные сети

Как восстановить черновики TikTok

Сумма геометрической прогрессии — примеры
Программирование

Сумма геометрической прогрессии — примеры