Модуль 26

React Router: клієнтська навігація

Ось твій урок. Приготуйся, зараз ми перетворимо твій веб-сайт із «старої скрипучої будівлі» на «сучасний швидкісний ліфт».


🎓 Урок: React Router та магія клієнтської навігації

Привіт, друзі! Це CS50 (жартую, але настрій у нас саме такий)! 👋

1. 🔥 Вступ: Чому сторінки «блимають»?

Уявіть, що ви живете у великому будинку. Кожного разу, коли ви хочете перейти з кухні у вітальню, вам доводиться... повністю руйнувати будинок і будувати його заново, але вже з вами у вітальні. Звучить як божевілля, правда?

Але саме так працює класичний веб!

Коли ви клікаєте на посилання <a> на старому сайті: 1. Браузер каже серверу: "Дай мені нову сторінку". 2. Екран стає білим (миготить). 😱 3. Браузер завантажує весь HTML, весь CSS і весь JavaScript заново. 4. Ви втрачаєте стан (наприклад, текст, який почали писати у формі).

Запитання до вас: Чи помічали ви, як працює Instagram, Facebook або Gmail? Ви клікаєте по вкладках, а перехід миттєвий. Нічого не блимає. Музика не переривається. Як вони це роблять?

Відповідь: Вони використовують SPA (Single Page Application) і Клієнтську навігацію.

Сьогодні ми навчимося робити це за допомогою бібліотеки React Router. Ми перестанемо "перебудовувати будинок" і просто будемо "міняти декорації" на одній і тій самій сцені.


2. 🧠 Теоретична база: Як обдурити браузер

Давайте заглянемо під капот.

Традиційно URL у браузері жорстко прив'язаний до файлу на сервері. site.com/about -> сервер шукає about.html.

У React все інакше. У нас є лише один файл index.html. Тож, як зробити так, щоб адреса в рядку змінювалася (/about), а браузер не перезавантажував сторінку?

Механізм (History API)

Браузер має вбудований інструмент — History API. Це як журнал капітана корабля. React Router каже браузеру:

"Слухай, зміни адресу в рядку на /about, але не роби запит на сервер. Я сам розберуся, що показати користувачеві".

Ключові гравці React Router (запам'ятайте цих чотирьох):

  1. <BrowserRouter> (Оболонка) — це наш "менеджер". Він слухає зміни в адресному рядку. Ми обгортаємо ним увесь додаток.
  2. <Routes> та <Route> (Правила) — це карта.
    • "Якщо адреса /, покажи компонент <Home />".
    • "Якщо адреса /about, покажи <About />".
  3. <Link> (Телепорт) — це заміна тегу <a>.
    • <a> викликає перезавантаження (погано для SPA).
    • <Link> просто змінює URL і каже React оновити екран (добре для SPA).

3. 🧪 Приклади: Від простого до магії

Давайте напишемо код. Припустимо, ми встановили бібліотеку: npm install react-router-dom.

Приклад 1: Мінімальна база

У нас є два компоненти: Home (Головна) і About (Про нас).

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

// Прості компоненти-сторінки
const Home = () => <h1>🏠 Ласкаво просимо додому!</h1>;
const About = () => <h1>ℹ️ Це сторінка про нас.</h1>;

function App() {
  return (
    <BrowserRouter>
      <nav>
        {/* УВАГА: Використовуємо Link, а не a */}
        <Link to="/">Головна</Link> | <Link to="/about">Про нас</Link>
      </nav>

      <Routes>
        {/* Тут відбувається магія підміни компонентів */}
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}

🤔 Що ви очікуєте побачити? Коли ви натиснете "Про нас", заголовок зміниться миттєво. Браузер не покаже значок "завантаження" біля вкладки. Це відчувається як мобільний додаток.


Приклад 2: Динамічні параметри (Реальна задача)

Уявіть, що у вас інтернет-магазин. У вас є 1000 товарів. Чи будете ви писати 1000 <Route path="/product-1" />, <Route path="/product-2" />?

Звісно, ні! Ми розробники, ми ліниві (у хорошому сенсі). Ми використовуємо шаблони.

import { useParams } from "react-router-dom";

const Product = () => {
  // useParams витягує те, що стоїть на місці :id
  const { id } = useParams(); 
  return <h1>📦 Ви переглядаєте товар з ID: {id}</h1>;
};

function App() {
  return (
    <BrowserRouter>
      <Routes>
        {/* Двокрапка означає "змінна частина" */}
        <Route path="/product/:id" element={<Product />} />
      </Routes>
    </BrowserRouter>
  );
}

Тепер, якщо ви перейдете на /product/shoes — побачите "Товар з ID: shoes". Якщо на /product/42 — "Товар з ID: 42". Один маршрут — нескінченна кількість сторінок.


Приклад 3: Сторінка "404" (Пастка)

Що буде, якщо користувач введе адресу, якої не існує? Наприклад, /abracadabra? Якщо ми не підготуємось, він побачить... порожній екран. Страшно!

const NotFound = () => <h2>🚫 Упс! Такої сторінки не існує.</h2>;

// У списку Routes додаємо в самому кінці:
<Route path="*" element={<NotFound />} />

Зірочка * означає "все інше". Якщо жоден маршрут вище не підійшов, React Router вибере цей.


4. 🛠 Практична частина

Час забруднити руки кодом! Відкрийте свій редактор.

Завдання 1: "База" Створіть додаток з трьома сторінками: Home, Gallery, Contact. Налаштуйте навігацію між ними використовуючи <Link>.

Завдання 2: "Детектив" Додайте в код звичайний тег <a href="/gallery">Gallery (Old)</a>. Відкрийте консоль браузера (F12), перейдіть на вкладку Network. 1. Клікніть на <Link>. Що змінилось у Network? (Майже нічого). 2. Клікніть на <a>. Що змінилось? (Купа запитів!). Поясніть собі вголос, чому так.

Завдання 3: "Профіль користувача" Створіть компонент UserProfile. Налаштуйте маршрут /user/:username. Зробіть так, щоб при переході на /user/admin сторінка вітала: "Привіт, admin!", а на /user/guest — "Привіт, guest!".

Завдання 4: "Активний стан" Замініть <Link> на <NavLink>. Це спеціальна версія посилання. Додайте стилі (наприклад, червоний колір), коли посилання активне. Підказка: NavLink автоматично додає клас active, якщо URL збігається.

Завдання 5: Міні-кейс "Віковий контроль" (Подумайте, як це зробити). У вас є маршрут /adults-only. Всередині компонента перевірте змінну const age = 15. Якщо менше 18 — покажіть текст "Вам сюди не можна". Якщо 18+ — покажіть контент.

Завдання 6: "А що, якщо..." Що, якщо у нас є навігаційне меню, яке має бути на всіх сторінках, крім сторінки "Вхід" (Login)? Спробуйте погуглити про "Layout routes" або подумайте, де розмістити <nav> відносно <Routes>.


5. 💡 Мислення як у розробника

Ось де новачки часто помиляються, а профі роблять інакше:

Помилка новачка: Використовують window.location.href = '/path' для переходу. Це вбиває весь сенс React, бо перезавантажує сторінку. ✅ Як думає профі: "Мені треба змінити сторінку з коду (наприклад, після успішного входу)? Я використаю хук useNavigate."

const navigate = useNavigate();
navigate('/dashboard'); // Чисто, швидко, по-ріактовськи

Помилка новачка: Пишуть всі маршрути в одному файлі App.js, перетворюючи його на "спагеті-код". ✅ Як думає профі: "Я винесу маршрути в окремий файл або буду групувати їх логічно. Чистота коду — запорука здоров'я проєкту."

💡 Порада з практики: Завжди обробляйте 404 помилку. Користувачі часто помиляються адресою. Красива сторінка "Не знайдено" з кнопкою "Повернутися на головну" значно краще утримує користувача, ніж білий екран смерті.


6. 🧩 Підсумок

Отже, що ми сьогодні зробили? 1. Зрозуміли, що SPA — це як театральна сцена, де змінюються лише актори, а не будівля. 2. Навчилися налаштовувати React Router (BrowserRouter, Routes, Route). 3. Освоїли безпечну навігацію через <Link> (ніяких перезавантажень!). 4. Створили динамічні сторінки за допомогою параметрів (:id).

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

🔜 Що далі? Ви можете ходити по кімнатах, це чудово. Але що, якщо деякі кімнати мають бути замкнені? На наступному уроці ми поговоримо про Protected Routes (Захищені маршрути) — як не пустити користувача на сторінку "Адмінка", якщо він не ввів пароль.

Це було CS50... тобто React Router. Успіхів у коді! 💻🚀