Тепер, коли у нас є налаштований роутер, нам потрібно якось переміщатися між сторінками. У світі HTML ми звикли використовувати тег <a>. Але в SPA це "заборонений прийом".
У цьому розділі ми розберемося, як правильно будувати навігацію, підсвічувати активні пункти меню та перенаправляти користувача програмно.
<a>Давайте спробуємо додати звичайне меню на нашу сторінку.
// ❌ НЕ РОБІТЬ ТАК В REACT ROUTER
function Navbar() {
return (
<nav>
<a href="/">Головна</a>
<a href="/about">Про нас</a>
</nav>
)
}
Якщо ви натиснете на таке посилання, ви побачите, як іконка завантаження браузера (спіннер на вкладці) почне крутитися. Що сталося?
/about.Це вбиває всю ідею SPA. Ми втратили стан і змусили користувача чекати.
<Link>React Router надає компонент-обгортку <Link>, який замінює <a>.
import { Link } from 'react-router-dom'
// ✅ Правильний підхід
function Navbar() {
return (
<nav>
<Link to="/">Головна</Link>
<Link to="/about">Про нас</Link>
</nav>
)
}
Під капотом <Link> все ще рендерить звичайний тег <a>. Це важливо для доступності (accessibility) та SEO — користувач може натиснути праву кнопку миші і обрати "Відкрити в новій вкладці".
Але <Link> додає власний обробник події onClick:
event.preventDefault(), щоб зупинити перезавантаження браузера.history.pushState), щоб змінити URL в адресному рядку.Все це відбувається миттєво.
<NavLink>Часто нам потрібно підсвітити посилання на сторінку, на якій ми зараз знаходимося (наприклад, зробити його жирним або змінити колір).
Звичайно, ми могли б перевіряти useLocation і додавати клас вручну, але React Router має спеціальний компонент: <NavLink>.
Він працює як <Link>, але приймає функцію або об'єкт у пропс className або style.
За замовчуванням, якщо посилання активне, NavLink додає клас active до елемента.
/* Стиль для активного класу */
.active {
color: red;
font-weight: bold;
}
import { NavLink } from 'react-router-dom'
;<nav>
<NavLink to="/">Головна</NavLink> {/* Якщо URL "/", отримає class="active" */}
<NavLink to="/about">Про нас</NavLink>
</nav>
Іноді вам потрібен повний контроль над класами (наприклад, якщо ви використовуєте 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). Це дозволяє показати користувачеві, що "щось відбувається", навіть до переходу.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(-1)Ви також можете використовувати 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!
Ці дані зберігаються в історії браузера.state буде втрачено (буде null).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.