логотип PurpleSchool
логотип PurpleSchool

Настройка маршрутизации в React с React Router

Автор

Олег Марков

Введение

Маршрутизация — это один из ключевых аспектов при создании современных одностраничных приложений (SPA) на React. С её помощью можно организовать перемещение пользователя между разными страницами и модулями приложения, не перезагружая всю страницу. Наиболее популярной библиотекой для организации маршрутов в React является React Router.

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

Что такое маршрутизация в React

В классических веб-приложениях переход между страницами сопровождался полной перезагрузкой. В одностраничных приложениях (SPA), построенных на React, переходы организуются “внутри” браузера без обновления всей страницы — за это отвечает система маршрутизации.

React Router позволяет “слушать” изменения адресной строки и отображать нужный компонент именно тогда, когда адрес совпадает с определённым маршрутом. Вы настраиваете структуру маршрутов, определяете, какие компоненты должны отображаться при каких URL, и Router обрабатывает логику переходов.

React Router - это библиотека для React, которая позволяет управлять маршрутизацией в веб-приложениях. Она позволяет создавать многостраничные приложения с навигацией между различными разделами. Если вы хотите научиться настраивать маршрутизацию в React с помощью React Router — приходите на наш большой курс Основы React, React Router и Redux Toolkit. На курсе 177 уроков и 17 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Основные сущности React Router

Перед установкой и реализацией давайте рассмотрим два ключевых понятия:

  • Маршрут (Route) — правило, при котором определённый путь URL связан с компонентом.
  • Роутер (Router) — оболочка, отслеживающая, какой путь сейчас в адресной строке, и выбирающая компонент, который нужно отобразить.

Есть три основных типа роутеров, которыми вы будете чаще всего пользоваться:

  • BrowserRouter — использует историю браузера (History API), оптимален для большинства современных веб-приложений.
  • HashRouter — маршруты создаются с помощью хэша (/#/about), обычно используется для простых или статических сайтов.
  • MemoryRouter — работает исключительно в памяти, подходит для тестирования и специальных сценариев.

Установка и настройка React Router

Сначала потребуется установить библиотеку. На момент написания статьи актуальна версия шестой (v6). Вот как это делается:

npm install react-router-dom
# или
yarn add react-router-dom

После установки можно приступать к первичной настройке.

Импортируйте необходимые компоненты

Вот пример импорта минимального набора для работы:

import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'

Оберните приложение в <BrowserRouter>

Это обязательно! Вот пример, как выглядит основной файл вашего приложения (чаще всего это src/App.js или src/index.js):

// Импортируем компоненты роутера
import { BrowserRouter } from 'react-router-dom'
import App from './App'

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

export default Root

Теперь роутер отслеживает изменения URL в вашем приложении.

Определите маршруты с помощью <Routes> и <Route>

Передадим в компонент <App> структуру маршрутов вашего приложения:

// Импортируем компоненты
import { Routes, Route, Link } from 'react-router-dom'

// Создаем несколько базовых компонентов для страниц
function Home() {
  return <h2>Главная страница</h2>
}

function About() {
  return <h2>О проекте</h2>
}

function NotFound() {
  return <h2>Страница не найдена</h2>
}

function App() {
  return (
    <div>
      {/* Простая навигация */}
      <nav>
        <Link to="/">Главная</Link> |{' '}
        <Link to="/about">О проекте</Link>
      </nav>
      {/* Определяем маршруты */}
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        {/* Этот маршрут сработает, если ничего не подошло */}
        <Route path="*" element={<NotFound />} />
      </Routes>
    </div>
  )
}

Объясню, что тут происходит:

  • В блоке <nav> мы используем компонент Link, чтобы создавать ссылки без перезагрузки страницы.
  • <Routes> ищет подходящий маршрут среди своих потомков <Route>.
  • Атрибут path определяет адрес, а element — какой компонент будет отображаться по этому адресу.
  • Символ * выступает как “catch-all” — если ни один путь не подошёл, показываем компонент “Страница не найдена”.

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

Вы уже видели использование компонента <Link>. Он позволяет переходить внутри приложения, не вызывая перезагрузку.

<Link to="/about">О проекте</Link>

Для программного перехода можно использовать хук useNavigate, если хотите управлять переходом не по клику, а, например, после сабмита формы или успешной авторизации:

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

function Example() {
  const navigate = useNavigate()

  function handleSuccess() {
    // Перенаправляем пользователя на главную страницу
    navigate('/')
  }

  return (
    <button onClick={handleSuccess}>Вернуться на главную</button>
  )
}

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

Часто бывает нужно создавать динамические страницы — например, для профиля пользователя или отображения товара по идентификатору. Для этого используются “параметры маршрута”.

Покажу на примере:

// Компонент для отображения профиля по ID
import { useParams } from 'react-router-dom'

function Profile() {
  // Получаем параметры из URL
  const { userId } = useParams()
  return <div>Профиль пользователя с ID: {userId}</div>
}

// Ваша настройка маршрута:
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/profile/:userId" element={<Profile />} />
</Routes>
  • В path используйте двоеточие для объявления идентификатора.
  • С помощью хука useParams легко получить значение этого параметра внутри компонента.

Вложенные маршруты

Иногда необходимо, чтобы внутри страницы отображались дочерние роуты — например, профиль пользователя может содержать вкладки “Информация”, “Настройки”, “Посты”.

Давайте рассмотрим, как настраиваются вложенные маршруты:

function Profile() {
  return (
    <div>
      <h2>Профиль</h2>
      <nav>
        <Link to="info">Информация</Link> |{' '}
        <Link to="posts">Посты</Link>
      </nav>
      {/* Здесь будут отображаться дочерние компоненты */}
      <Outlet />
    </div>
  )
}

function Info() {
  return <div>Информация о пользователе</div>
}

function Posts() {
  return <div>Список постов пользователя</div>
}

// Теперь определим маршруты для профиля и его "вкладок":
<Routes>
  <Route path="profile/:userId" element={<Profile />}>
    <Route path="info" element={<Info />} />
    <Route path="posts" element={<Posts />} />
  </Route>
</Routes>
  • Для отображения дочерних маршрутов должен использоваться компонент <Outlet />.
  • Обратите внимание, дочерние маршруты пишутся относительно родителя.

Redirect — перенаправление между маршрутами

Бывает, нужно перенаправить пользователя на другой маршрут. В React Router v6 для этого применяется компонент <Navigate>:

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

// Этот компонент перенаправит на главную, если не выполнено условие
function ProtectedRoute({ isAuth, children }) {
  if (!isAuth) {
    return <Navigate to="/login" replace />
  }
  return children
}

Передавая prop replace, вы удаляете предыдущую запись из истории, чтобы пользователь не мог вернуться кнопкой “назад”.

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

Если в вашем приложении есть приватные (закрытые) страницы, которые видны только авторизованным пользователям, подойдёт паттерн защищённых маршрутов.

Вот реальный пример:

function PrivateRoute({ isAuth, children }) {
  if (!isAuth) {
    // Если пользователь не авторизован — перенаправляем на login
    return <Navigate to="/login" replace />
  }
  // Если авторизован — разрешаем доступ к children (например, странице профиля)
  return children
}

// Используем защищённый маршрут:
<Routes>
  <Route path="/profile" element={
    <PrivateRoute isAuth={userLoggedIn}>
      <Profile />
    </PrivateRoute>
  } />
  <Route path="/login" element={<Login />} />
</Routes>
  • Вы можете использовать глобальное состояние (Context, Redux, Zustand и т.д.) для отслеживания авторизации.

404 и обработка “не найдено”

Очень важно учитывать ситуацию, когда пользователь перешёл по несуществующему адресу. Для этого добавляют маршрут с path="*".

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

Можно сделать этот компонент более информативным, добавив кнопку возвращения назад или ссылку на главную страницу.

Lazy loading и разделение кода

Для ускорения загрузки SPA принято “разделять” код по маршрутам — загружать только тот компонент, который нужен прямо сейчас. React поддерживает это с помощью React.lazy и Suspense.

import { Routes, Route } from 'react-router-dom'
import React, { Suspense, lazy } from 'react'

// Импортируем только когда понадобится
const Home = lazy(() => import('./Home'))
const About = lazy(() => import('./About'))

function App() {
  return (
    <Suspense fallback={<div>Загрузка...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  )
}
  • Это позволяет существенно экономить на времени загрузки, если у вас большое приложение.

Использование навигационных хуков

Вам часто понадобятся следующие хуки:

  • useNavigate() — для программной навигации.
  • useParams() — для извлечения динамических параметров из адреса.
  • useLocation() — возвращает объект с данными о текущем пути (pathname, search, hash и др.).
  • useMatch() — сопоставляет путь с текущим адресом.

Пример использования:

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

function LocationLogger() {
  const location = useLocation()

  // Показываем текущий url путь
  return <div>Текущий путь: {location.pathname}</div>
}

Обработка query-параметров (строки запроса)

Query-параметры хранятся в строке поиска (?key=value). Для их получения используйте useLocation и классический URLSearchParams:

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

function SearchComponent() {
  const { search } = useLocation()
  // Преобразуем в объект для удобства работы
  const params = new URLSearchParams(search)
  const query = params.get('query')

  return <div>Ваш поисковый запрос: {query}</div>
}

Организация структуры файлов и маршрутов

Для крупных приложений рекомендуется составлять дерево маршрутов по файлам. Вот один из популярных паттернов:

  • routes/
    • Home.js
    • Profile.js
    • ProfileInfo.js
    • ProfilePosts.js
    • и т.д.

В App.js только структура роутера, а остальной контент выносится в логику страниц.

Разбор основных ошибок

  • Не обернули приложение в <BrowserRouter> — роутинг работать не будет.
  • Использовали component вместо element в <Route> (v6 перешел на новый синтаксис).
  • Не поставили <Outlet /> в родительском компоненте с вложенными маршрутами — дочерние руты не работают.
  • Совпадение пути — в v6 путь должен быть точным, учитывайте это при использовании вложенности.

Заключение

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

React Router позволяет создавать сложные приложения с навигацией. Для полноценной разработки необходимо уметь управлять состоянием приложения. На курсе Основы React, React Router и Redux Toolkit вы изучите все необходимое. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в основы React уже сегодня.

Частозадаваемые технические вопросы по теме и ответы

Используйте хук useNavigate:

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

function MyButton() {
  const navigate = useNavigate()
  return (
    <button onClick={() => navigate('/about')}>Перейти</button>
  )
}

Как получить несколько параметров из адреса, например /post/:postId/comment/:commentId?

Объявите маршрут так:

<Route path="/post/:postId/comment/:commentId" element={<MyComp />} />

Внутри компонента:

const { postId, commentId } = useParams()

Как правильно реализовать редирект на внешний сайт при переходе по определённому пути?

Создайте компонент, который с помощью эффекта меняет window.location:

function ExternalRedirect() {
  React.useEffect(() => {
    window.location.href = 'https://external.site'
  }, [])
  return null
}
<Route path="/external" element={<ExternalRedirect />} />

Как повторно использовать логику защищённых маршрутов для нескольких страниц?

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

Почему вложенный маршрут не отображается?

Проверьте, что:

  • Родительский компонент содержит <Outlet />.
  • Путь дочернего маршрута не начинается со слеша, а прописан относительно родителя.
  • Родительский маршрут корректно определён с элементом и дочерними <Route>.
Стрелочка влевоКак подключить Tailwind к ReactРабота с Redux в React-приложенииСтрелочка вправо

Постройте личный план изучения React до уровня Middle — бесплатно!

React — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React

Открыть базу знаний

Лучшие курсы по теме

изображение курса

React и Redux Toolkit

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий