React Router - Бібліотека маршрутизації для React

Інсталяця

reactrouter.com

У React немає вбудованого модуля маршрутизації, тому використовується React Router - Бібліотека маршрутизації для React. Так само, як React надає нам набір примітивів для створення інтерфейсу користувача та роботи зі станом, React Router надає набір компонентів та хуків для створення маршрутизації, управління історією навігації користувача та відображення різних компонетів в залежності від поточного значення URL в адресному рядку браузера.

npm install react-router-dom

Первинне налаштування

1. обернути компонентом BrowserRouter всі програми в main.jsx.

import { BrowserRouter } from "react-router-dom";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);

2. В підлеглих компонентах використовувати routes і route Приклад:

// src/components/App.jsx
import { Routes, Route } from "react-router-dom";
import Home from "path/to/pages/Home";
import About from "path/to/pages/About";
import Products from "path/to/pages/Products";
export const App = () => {
return (
<div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/products" element={<Products />} />
</Routes>
</div>
);
};

Конвенція структури файлів програми передбачає зберігання всіх компонентів у папці src/components. Компонент сторінки це звичайнісінький React-компонент, який містить у собі розмітку цілої сторінки вашої програми. Для зручності та структурованості такі компоненти зберігаються окремо від усіх, у папці src/pages.

Сторінка помилки навігації

Що буде, якщо користувач перейде за посиланням /non-existing-route або будь-якому іншому, якого немає в нашому додатку? Він побачить порожню вкладку браузера, без будь-якого контенту, оскільки жоден з описаних нами <Route> не підійде. Для цього до кінця списку маршрутів додамо ще один <Route>, який збігатиметься з будь-яким URL, але він буде обраний тільки в тому випадку, якщо жоден інший маршрут не підійде.

import { Routes, Route } from "react-router-dom";
import Home from "path/to/pages/Home";
import About from "path/to/pages/About";
import Products from "path/to/pages/Products";
import NotFound from "path/to/pages/NotFound";
const App = () => {
return (
<div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/products" element={<Products />} />
<Route path="*" element={<NotFound />} />
</Routes>
</div>
);
};

Компоненти <Link> та <NavLink>

Для створення навігації не можна використовувати звичайний тег <a href=«/about»>. При кліку, замість того щоб змінити URL на поточній сторінці, і дозволити маршрутизатору виконати навігацію на стороні клієнта, браузер перезавантажить сторінку. Для створення посилань використовуються компоненти <Link> та <NavLink>. Вони рендерять тег <a>, але стандартна поведінка посилання змінена так, що при натисканні просто оновлюється URL в адресному рядку браузера, без перезавантаження сторінки.

// src/components/App.jsx
import { Routes, Route, NavLink } from "react-router-dom";
import clsx from 'clsx';
import Home from "path/to/pages/Home";
import About from "path/to/pages/About";
import Products from "path/to/pages/Products";
import NotFound from 'path/to/pages/NotFound';
import css from './App.module.css';
const buildLinkClass = ({ isActive }) => {
return clsx(css.link, isActive && css.active);
};
export const App = () => {
return (
<div>
<nav className={css.nav}>
<NavLink to="/" className={buildLinkClass}>
Home
</NavLink>
<NavLink to="/about" className={buildLinkClass}>
About
</NavLink>
<NavLink to="/products" className={buildLinkClass}>
Products
</NavLink>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/products" element={<Products />} />
<Route path="*" element={<NotFound />} />
</Routes>
</div>
);
};

URL-параметри

<Route path="/blog/:postId" element={<BlogPost />} />

Додамо до нашої програми маршрут сторінки одного продукту з адресою /products/:productId. Це окрема сторінка, ніяк не прив'язана до /products - сторінці відображення всіх продуктів.

// src/components/App.jsx
import { Routes, Route, Link } from "react-router-dom";
import Home from "path/to/pages/Home";
import About from "path/to/pages/About";
import Products from "path/to/pages/Products";
import NotFound from "path/to/pages/NotFound";
import ProductDetails from "path/to/pages/ProductDetails";
export const App = () => {
return (
<div>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/products">Products</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/products" element={<Products />} />
<Route path="/products/:productId" element={<ProductDetails />} />
<Route path="*" element={<NotFound />} />
</Routes>
</div>
);
};

Хук UseParams

Хук useParams

Вкладені маршрути

Вкладені маршрути дозволяють описувати логіку «підсторінок», тобто якийсь URL по якому крім батьківського компонента цілої сторінки буде відображатися ще якийсь дочірній, вкладений компонент.

Наприклад, нам необхідно щоб на /about/mission, /about/team та /about/reviews крім контенту сторінки «Про нас» відображалася ще якась додаткова, більш специфічна інформація. Нехай це буде кілька різноманітних компонентів: стаття про місію нашої компанії, галерея з інформацією про співробітників та відгуки користувачів.

// ✅ Правильно
<Route path="/about" element={<About />}>
<Route path="mission" element={<Mission />} />
<Route path="team" element={<Team />} />
<Route path="reviews" element={<Reviews />} />
</Route>

Ми декларативно вклали дочірні маршрути всередину батьківського <Route>. Саме такий синтаксис вказує на вкладений маршрут, компонент якого буде відображатися десь усередині батьківського компонента.

Значення пропсу path у вкладеного маршруту вказується відносно батьківського, саме тому ми передали значення path=«mission», а не повний шлях path=«/about/mission».

Відносні шляхи записуються без провідного символу /, тобто path=«mission», а не path=«/mission». Якщо додати слеш, то ми навпаки створимо окремий маршрут /mission та зламаємо логіку маршрутизації.

Налаштування Vercel

vercel - для публікації проекту з Гіту в інтет\хостинг