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

Динамічна Навігація

Тепер, коли у нас є налаштований роутер, нам потрібно якось переміщатися між сторінками. У світі HTML ми звикли використовувати тег <a>. Але в SPA це "заборонений прийом".

Динамічна Навігація

Тепер, коли у нас є налаштований роутер, нам потрібно якось переміщатися між сторінками. У світі HTML ми звикли використовувати тег <a>. Але в SPA це "заборонений прийом".

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

1. Проблема тегу <a>

Давайте спробуємо додати звичайне меню на нашу сторінку.

// ❌ НЕ РОБІТЬ ТАК В REACT ROUTER
function Navbar() {
    return (
        <nav>
            <a href="/">Головна</a>
            <a href="/about">Про нас</a>
        </nav>
    )
}

Якщо ви натиснете на таке посилання, ви побачите, як іконка завантаження браузера (спіннер на вкладці) почне крутитися. Що сталося?

  1. Браузер отримав наказ перейти на /about.
  2. Він вивантажив весь ваш React-додаток з пам'яті.
  3. Він зробив запит на сервер за новим HTML.
  4. Він знову завантажив JS, розпарсив його і запустив React з нуля.

Це вбиває всю ідею SPA. Ми втратили стан і змусили користувача чекати.

React Router надає компонент-обгортку <Link>, який замінює <a>.

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

// ✅ Правильний підхід
function Navbar() {
    return (
        <nav>
            <Link to="/">Головна</Link>
            <Link to="/about">Про нас</Link>
        </nav>
    )
}

Як це працює? (Under the Hood)

Під капотом <Link> все ще рендерить звичайний тег <a>. Це важливо для доступності (accessibility) та SEO — користувач може натиснути праву кнопку миші і обрати "Відкрити в новій вкладці".

Але <Link> додає власний обробник події onClick:

  1. Він перехоплює клік.
  2. Викликає event.preventDefault(), щоб зупинити перезавантаження браузера.
  3. Використовує History API (history.pushState), щоб змінити URL в адресному рядку.
  4. Повідомляє React Router про зміну URL, щоб той оновив UI.

Все це відбувається миттєво.

Часто нам потрібно підсвітити посилання на сторінку, на якій ми зараз знаходимося (наприклад, зробити його жирним або змінити колір).

Звичайно, ми могли б перевіряти useLocation і додавати клас вручну, але React Router має спеціальний компонент: <NavLink>.

Він працює як <Link>, але приймає функцію або об'єкт у пропс className або style.

Базове використання (CSS-клас)

За замовчуванням, якщо посилання активне, NavLink додає клас active до елемента.

styles.css
/* Стиль для активного класу */
.active {
    color: red;
    font-weight: bold;
}
import { NavLink } from 'react-router-dom'
;<nav>
    <NavLink to="/">Головна</NavLink> {/* Якщо URL "/", отримає class="active" */}
    <NavLink to="/about">Про нас</NavLink>
</nav>

Просунуте використання (Render Props)

Іноді вам потрібен повний контроль над класами (наприклад, якщо ви використовуєте Tailwind CSS). Ви можете передати функцію в className:

<NavLink
    to="/messages"
    className={
        ({ isActive, isPending }) =>
            isActive
                ? 'text-blue-500 font-bold underline' // Класи для активного стану
                : isPending
                  ? 'text-gray-400' // Стан завантаження (актуально для Data Router)
                  : 'text-black hover:text-blue-300' // Звичайний стан
    }
>
    Повідомлення
</NavLink>
Параметр isPending стає true, коли ми клікнули на посилання, але дані для наступної сторінки ще завантажуються (через loader). Це дозволяє показати користувачеві, що "щось відбувається", навіть до переходу.

4. Програмна Навігація: useNavigate

Іноді нам потрібно перенаправити користувача не після кліку на посилання, а в результаті якоїсь дії. Наприклад:

  • Після успішної відправки форми.
  • Після логіну.
  • Після завершення таймера.

Для цього використовується хук useNavigate.

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

function LoginForm() {
    const navigate = useNavigate()

    async function handleSubmit(event) {
        event.preventDefault()
        await loginUser() // Якась асинхронна дія

        // Перенаправлення на сторінку профілю
        navigate('/profile')

        // АБО: Заміна поточної історії (щоб "Назад" не повертало на логін)
        // navigate("/profile", { replace: true });
    }

    return <form onSubmit={handleSubmit}>...</form>
}

Ви також можете використовувати navigate для переміщення по історії (аналог кнопки "Назад" у браузері):

<button onClick={() => navigate(-1)}>Повернутися назад</button>
<button onClick={() => navigate(1)}>Вперед</button>

Іноді ви хочете передати невеликі шматки даних на наступну сторінку, не додаючи їх в URL (щоб URL залишався чистим).

// Відправник
;<Link to="/checkout" state={{ from: 'cart', discount: 10 }}>
    Оформити замовлення
</Link>

// Отримувач (CheckoutPage.jsx)
import { useLocation } from 'react-router-dom'

function CheckoutPage() {
    const location = useLocation()
    const { from, discount } = location.state || {} // Завжди перевіряйте на null!

    return <div>Знижка: {discount}%</div>
}
Обережно зі state! Ці дані зберігаються в історії браузера.
  1. Якщо користувач скопіює посилання і відкриє в новій вкладці — state буде втрачено (буде null).
  2. Це погане місце для важливих даних. Використовуйте це тільки для UI-дрібниць (наприклад, "звідки ми прийшли", щоб правильно показати кнопку "Назад").

6. View Transitions (v7)

React Router v7 має вбудовану підтримку View Transitions API. Це дозволяє робити плавні анімації між сторінками, які раніше були можливі тільки в нативних додатках.

Щоб увімкнути цю магію, просто додайте проп viewTransition до вашого посилання:

<Link to="/details" viewTransition>
    Відкрити деталі
</Link>

Або використовуйте опцію в useNavigate:

navigate("/details", { viewTransition: true });

Тепер, коли ви переходите за посиланням, браузер зробить "знімок" старого стану і плавно анімує перехід до нового.

Резюме

ІнструментКоли використовувати
<Link>Стандартні посилання для навігації.
<NavLink>Посилання в меню, табах, списках, де треба виділяти поточний елемент.
useNavigateПерехід після виконання дії (сабміт форми, ефект).
state propПередача невидимих даних між маршрутами (обережно).

Тепер ми вміємо створювати маршрути і ходити по них. Але справжня сила React Router розкривається, коли ми починаємо вкладати маршрути один в одного. Наступна зупинка — Nested Routes.

Copyright © 2026