React Router: Навігаційна система сучасного вебу

Налаштування та Базовий Роутинг

Ми починаємо нашу практичну подорож. У цьому розділі ми інтегруємо React Router у проект і налаштуємо перші маршрути.

Налаштування та Базовий Роутинг

Ми починаємо нашу практичну подорож. У цьому розділі ми інтегруємо React Router у проект і налаштуємо перші маршрути.

Ми будемо використовувати Data Router (доступний з v6.4), оскільки це сучасний стандарт, який відкриває доступ до потужних функцій завантаження даних.

1. Встановлення

Для початку додамо пакет до нашого проекту. React Router розділений на кілька пакетів, але для веб-розробки нам потрібен лише один основний.

Встановлення пакету

Виконайте команду у терміналі вашого проекту:

npm install react-router-dom

Перевірка package.json

Переконайтеся, що версія не нижче 7.0.0 (або 6.4.0, якщо ви ще не оновилися). Це критично для роботи API, які ми будемо вивчати.

2. Старий vs Новий підхід

Якщо ви раніше працювали з React Router, ви могли бачити такий код:

// ❌ Застарілий підхід (Legacy Router)
// Детальніше про цей підхід читайте в окремому розділі: [Legacy Routing](./07.legacy-routing.md)
<BrowserRouter>
    <Routes>
        <Route path="/" element={<Home />} />
    </Routes>
</BrowserRouter>

Сучасний підхід виглядає інакше. Ми відокремлюємо конфігурацію маршрутів від рендерингу.

// ✅ Сучасний підхід (Data Router)
const router = createBrowserRouter([...]);

<RouterProvider router={router} />

Чому це важливо? (Архітектурний відступ)

Чому розробники React Router змушують нас писати більше коду?

У старому підході роутер був просто компонентом всередині дерева React. Він дізнавався про маршрут лише тоді, коли React починав рендерити додаток. Це створювало проблему Waterfalls (водоспадів) при завантаженні даних:

  1. Завантажується JS.
  2. React рендерить <App>.
  3. React доходить до <Route>, рендерить компонент сторінки.
  4. useEffect у компоненті починає тягнути дані.

З createBrowserRouter, конфігурація винесена за межі дерева рендеру. Роутер знає, що потрібно завантажити, ще до того, як React намалює перший піксель. Це дозволяє завантажувати дані паралельно з кодом сторінки.

3. Створення Конфігурації Роутера

Давайте створимо наш перший роутер. Для початку підготуємо прості компоненти-заглушки, щоб було що показувати.

Тепер налаштуємо сам роутер у точці входу вашого додатку (зазвичай main.jsx або index.jsx).

src/main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
// 1. Імпортуємо необхідні методи
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import HomePage from './pages/HomePage'
import AboutPage from './pages/AboutPage'

// 2. Створюємо конфігурацію маршрутів
// Це масив об'єктів, де кожен об'єкт — це окремий маршрут
const router = createBrowserRouter([
    {
        path: '/', // URL шлях
        element: <HomePage />, // Компонент, який треба показати
    },
    {
        path: '/about',
        element: <AboutPage />,
    },
])

ReactDOM.createRoot(document.getElementById('root')).render(
    <React.StrictMode>
        {/* 3. Передаємо роутер у провайдер */}
        <RouterProvider router={router} />
    </React.StrictMode>,
)

Анатомія RouteObject

Давайте розберемо об'єкт конфігурації маршруту:

{
  path: "/about",
  element: <AboutPage />,
  // ...інші властивості, які ми вивчимо пізніше (loader, action, errorElement)
}
  • path: Частина URL після домену. Наприклад, для mysite.com/about шлях буде /about.
    • / — це кореневий маршрут (головна сторінка).
  • element: React-елемент (JSX), який потрібно відрендерити, коли URL збігається з path. Важливо передавати саме <Component />, а не просто Component.

4. Обробка помилок (404 Not Found)

Що станеться, якщо користувач перейде за посиланням /contact, яке ми не описали? React Router за замовчуванням викине помилку в консоль і покаже свій стандартний (досить страшний) екран помилки.

Ми можемо (і повинні) налаштувати власний екран помилки. У Data Router для цього є спеціальна властивість errorElement. Вона спрацьовує не тільки на 404, а й на будь-які помилки під час рендеру чи завантаження даних у цьому маршруті.

Створимо компонент помилки:

src/pages/ErrorPage.jsx
import { useRouteError } from 'react-router-dom'

export default function ErrorPage() {
    const error = useRouteError()
    console.error(error)

    return (
        <div id="error-page">
            <h1>Ой!</h1>
            <p>Сталася неочікувана помилка.</p>
            <p>
                {/* Показуємо текст помилки або статус (наприклад, 404 Not Found) */}
                <i>{error.statusText || error.message}</i>
            </p>
        </div>
    )
}

Тепер додамо його до кореневого маршруту.

src/main.jsx
const router = createBrowserRouter([
    {
        path: '/',
        element: <HomePage />,
        errorElement: <ErrorPage />, // Додаємо обробку помилок    },
    {
        path: '/about',
        element: <AboutPage />,
    },
])
Зверніть увагу: якщо ви додасте errorElement тільки до /, а користувач перейде на неіснуючий /foobar, роутер спробує знайти маршрут. Оскільки /foobar не існує, він не зможе зіставити його з жодним маршрутом і... насправді тут є нюанс.Щоб зловити "Global 404", нам зазвичай потрібен Root Layout (кореневий макет), який обгортає всі інші маршрути. Про це ми поговоримо детально в розділі "Вкладені маршрути". На поточному етапі, якщо маршрут не знайдено, роутер покаже дефолтну помилку, якщо ми не налаштували специфічний маршрут для * або не використовуємо вкладеність.Але в рамках Data Router, помилки спливають наверх ("bubbling"). Якщо ми зробимо кореневий маршрут батьківським для всіх інших, errorElement перехопить усе. Поки що просто пам'ятайте про існування цієї властивості.

Резюме

  • Ми використовуємо createBrowserRouter для створення об'єкта роутера.
  • RouterProvider — це компонент, який зв'язує цей об'єкт з React-деревом.
  • Маршрути визначаються як об'єкти з path та element.
  • errorElement дозволяє елегантно обробляти помилки.

Тепер у нас є робочий роутер, але ми досі змушені вручну вводити URL у браузер. У наступному розділі ми навчимося створювати посилання та навігацію всередині додатку.

Copyright © 2026