React Маршрутизация

Для предоставления возможности маршрутизации в приложениях React, существует специальная библиотека React Router.

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

React Router считается стандартной библиотекой маршрутизации для приложений на React. Она позволяет:

  • Создавать несколько страниц в вашем одностраничном приложении
  • Обрабатывать параметры и строки запросов в URL
  • Управлять историей браузера и навигацией
  • Создавать вложенные маршруты и макеты
  • Реализовывать защищённые маршруты для аутентификации

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


Установка React Router

В командной строке перейдите в каталог вашего проекта и выполните следующую команду для установки пакета:


npm install react-router-dom


Оборачиваем ваше приложение в BrowserRouter

Ваше приложение должно быть обернуто компонентом BrowserRouter, чтобы включить маршрутизацию:


function App() {
  return (
    <BrowserRouter>
      {/* Содержимое вашего приложения */}
    </BrowserRouter>
  );
}


Создание представлений

Чтобы продемонстрировать маршрутизацию, мы создадим три страницы (представления) в нашем приложении: Главная, О нас и Контакты.

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

Пример


function Home() {
  return <h1>Главная страница</h1>;
}

function About() {
  return <h1>Страница О нас</h1>;
}

function Contact() {
  return <h1>Контактная страница</h1>;
}


Базовая маршрутизация

React Router использует три основных компонента для базовой маршрутизации:

  • Link: создаёт навигационные ссылки, обновляющие URL
  • Routes: контейнер для всех ваших маршрутов
  • Route: определяет сопоставление между путями URL и компонентами

Давайте добавим навигационные ссылки и маршруты для каждой ссылки:

Пример

Учтите, что нам нужно импортировать компоненты BrowserRouter, Routes, Route и Link из библиотеки react-router-dom.


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

function Home() {
  return <h1>Главная страница</h1>;
}

function About() {
  return <h1>Страница О нас</h1>;
}

function Contact() {
  return <h1>Контактная страница</h1>;
}

function App() {
  return (
    <BrowserRouter>
      {/* Навигация */}
      <nav>
        <Link to="/">Главная</Link> |{" "}
        <Link to="/about">О нас</Link> |{" "}
        <Link to="/contact">Контакты</Link>
      </nav>

      {/* Маршруты */}
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

В этом примере:

  • BrowserRouter оборачивает ваше приложение и включает функциональность маршрутизации
  • Компоненты Link создают навигационные ссылки
  • Элементы Routes и Route определяют вашу конфигурацию маршрутизации

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

Вы можете разместить один маршрут внутри другого маршрута, что называется вложенными маршрутами.

Вложенные маршруты позволяют изменять части страницы при переходе по новому URL, при этом остальные части остаются неизменёнными или не перегружаются, почти как страница внутри страницы.

Возьмем предыдущий пример и добавим два новых компонента, которые будут отображаться внутри компонента Products.

Один назовём CarProducts, а другой — BikeProducts:

Пример

Учтите, что нам также потребуется импортировать компонент Outlet из библиотеки react-router-dom.


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

function Home() {
  return <h1>Главная страница</h1>;
}

function Products() {
  return (
    <div>
      <h1>Страница товаров</h1>
      <nav style={{ marginBottom: '20px' }}>
        <Link to="/products/car">Автомобили</Link> |{" "}
        <Link to="/products/bike">Велосипеды</Link>
      </nav> 
      <Outlet /> 
    </div>
  );
}

function CarProducts() {
  return (
    <div>
      <h2>Автомобили</h2>
      <ul>
        <li>Audi</li>
        <li>BMW</li>
        <li>Volvo</li>
      </ul>
    </div>
  );
}

function BikeProducts() {
  return (
    <div>
      <h2>Велосипеды</h2>
      <ul>
        <li>Yamaha</li>
        <li>Suzuki</li>
        <li>Honda</li>
      </ul>
    </div>
  );
}

function Contact() {
  return <h1>Контактная страница</h1>;
}

function App() {
  return (
    <BrowserRouter>
      {/* Навигация */}
      <nav>
        <Link to="/">Главная</Link> |{" "}
        <Link to="/products">Продукты</Link> |{" "}
        <Link to="/contact">Контакты</Link>
      </nav>

      {/* Маршруты */}
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/products" element={<Products />}>
          <Route path="car" element={<CarProducts />} />
          <Route path="bike" element={<BikeProducts />} />
        </Route>
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

Важные замечания по данному примеру:

  • Элемент <Outlet /> в компоненте Products определяет место, куда будет отображено содержимое дочернего маршрута.
  • Элемент Routes содержит маршруты к компонентам CarProducts и BikeProducts как дочерним маршрутам родительского маршрута Products.
  • Структура URL:
    Структура URL относительна к пути родительского маршрута. Например:
    • Переход по /products/car вызывает отображение компонента CarProducts.
    • Переход по /products/bike вызывает отображение компонента BikeProducts.

Стилизация активных ссылок

Есть специальная версия компонента Link, называемая NavLink, которая знает, активна ссылка или нет.

Компонент NavLink особенно полезен для:

  • Меню навигации
  • Хлебных крошек
  • Закладок

NavLink считается активной, если текущий URL соответствует её свойству to.

Компонент NavLink облегчает стилизацию активных ссылок.

Возьмем предыдущий базовый пример и добавим стили для активных ссылок с помощью NavLink:

Пример

Создайте новый элемент navLinkStyles и замените <Link> на <NavLink> в компоненте App.

Учтите, что нам также потребуется импортировать компонент NavLink из библиотеки react-router-dom.


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

// Функциональный стиль для активных ссылок
const navLinkStyles = ({ isActive }) => ({
  color: isActive ? '#007bff' : '#333',
  textDecoration: isActive ? 'none' : 'underline',
  fontWeight: isActive ? 'bold' : 'normal',
  padding: '5px 10px'
});

function Home() {
  return <h1>Главная страница</h1>;
}

function About() {
  return <h1>Страница О нас</h1>;
}

function Contact() {
  return <h1>Контактная страница</h1>;
}

function App() {
  return (
    <BrowserRouter>
      {/* Навигация с использованием NavLink для активного стиля */}
      <nav style={{ marginBottom: '20px' }}>
        <NavLink to="/" style={navLinkStyles}>Главная</NavLink> |{" "}
        <NavLink to="/about" style={navLinkStyles}>О нас</NavLink> |{" "}
        <NavLink to="/contact" style={navLinkStyles}>Контакты</NavLink>
      </nav>

      {/* Маршруты */}
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}


Параметры URL

Параметры URL — это переменные, которые вы можете добавлять в путь маршрута. Обычно они используются для передачи данных между компонентами.

В URL http://localhost:5173/customer/Tobias параметром URL является Tobias.

Параметры URL позволяют создавать динамичные маршруты, где часть URL может меняться. Их можно рассматривать как переменные в вашем URL.

React Router предоставляет хук useParams, который позволяет получить доступ к этим параметрам в ваших компонентах.

Вот простой пример страницы приветствия, которая может поприветствовать разных клиентов:

Пример


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

function Info() {
  const { firstname } = useParams();
  return <h1>Здравствуйте, {firstname}!</h1>;
}

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/customer/Emil">Эмил</Link> | 
        <Link to="/customer/Tobias">Тобиас</Link> |
        <Link to="/customer/Linus">Линус</Link>
      </nav>

      <Routes>
        <Route path="/customer/:firstname" element={<Info />} />
      </Routes>
    </BrowserRouter>
  );
}

В этом примере:

  • :firstname в пути маршрута — это параметр URL
  • При переходе по ссылке /customer/Emil вы увидите "Здравствуйте, Эмил!"
  • При переходе по ссылке /customer/Tobias вы увидите "Здравствуйте, Тобиас!"
  • При переходе по ссылке /customer/Linus вы увидите "Здравствуйте, Линус!"
  • Вы можете использовать любое имя в URL, и приветствие сработает! Попробуйте перейти по адресу http://localhost:5173/customer/John.