Олег Марков
Настройка маршрутизации в 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 уже сегодня.
Частозадаваемые технические вопросы по теме и ответы
Как заменить переход на другую страницу по клику на <button>
, а не <Link>
?
Используйте хук 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>
.
Постройте личный план изучения React до уровня Middle — бесплатно!
React — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по React
Лучшие курсы по теме

React и Redux Toolkit
Антон Ларичев
TypeScript с нуля
Антон Ларичев