Перетворити односторінковий додаток (SPA) на багатосторінковий інтернет-магазин. Навчитися встановлювати маршрутизатор react-router-dom, налаштовувати шляхи до сторінок (Головна, Кошик/Оформлення) та безпечно переходити між ними за допомогою компонента <Link> без стирання глобального стану додатку.
react-router-dom через npm.<BrowserRouter>.Home.jsx та CheckoutPage.jsx.<Routes> та <Route>.<a> на компоненти <Link to="...">.Увага: Продовжуємо роботу в проекті “TechShop” (React). До цього моменту весь наш код жив у одному файлі App.jsx, який стає занадто великим. Пора навести лад в архітектурі.
npm install react-router-dom.npm run dev.src створіть папку pages.Створіть файл src/pages/Home.jsx. Перенесіть туди ВЕСЬ ВМІСТ малювання карток товарів та завантаження через fetch() з вашого старого App.jsx (переконайтеся, що ви імпортували useEffect, useState та ProductCard).
// src/pages/Home.jsx
import { useState, useEffect } from "react";
import { ProductCard } from "../components/ProductCard";
export function Home() {
const [products, setProducts] = useState([]);
// ... логіка fetchProducts() з ПР17
return (
<main className="page-layout">
<h2>Популярні товари</h2>
{/* ... Ваш мапинг карток */}
</main>
);
}
Створіть файл src/pages/CheckoutPage.jsx. Всередину нього помістіть заголовок та вашу форму (її ми створювали у папці компонентів у ПР №16).
// src/pages/CheckoutPage.jsx
import { CheckoutForm } from "../components/CheckoutForm";
export function CheckoutPage() {
return (
<main className="page-layout">
<h2>Оформлення замовлення</h2>
<CheckoutForm />
</main>
);
}
src/main.jsx.Імпортуйте <BrowserRouter> та обгорніть ним <App />.
import { BrowserRouter } from "react-router-dom";
createRoot(document.getElementById("root")).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
);
App.jsx:
App.jsx (він у нас тепер майже порожній).<Routes>, <Route> з react-router-dom.Встановіть Header поверх змінної частини екрану:
// src/App.jsx
import { Routes, Route } from "react-router-dom";
import { Header } from "./components/Header";
import { Home } from "./pages/Home";
import { CheckoutPage } from "./pages/CheckoutPage";
function App() {
return (
<div className="app-container">
{/* Header висить на ВСІХ сторінках */}
<Header />
{/* А тут контент змінюється залежно від адреси (URL) */}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/checkout" element={<CheckoutPage />} />
{/* Можна додати сторінку 404 */}
<Route
path="*"
element={
<main>
<h2>Сторінка не знайдена</h2>
</main>
}
/>
</Routes>
</div>
);
}
export default App;
Link):
src/components/Header.jsx.<a href="/checkout">Кошик</a>, то під час кліку ब्राउзер перезавантажить сторінку повністю (моргне екран, всі стани React зітруться).Імпортуйте <Link> та замініть звичайні посилання.
import { Link } from "react-router-dom";
export function Header() {
return (
<header className="header">
{/* Повернення на головну */}
<div className="logo">
<Link to="/">TechShop React</Link>
</div>
<div className="user-actions">
{/* Перехід на оформлення */}
<Link to="/checkout" className="btn btn-cart">
Кошик
</Link>
</div>
</header>
);
}
/checkout, форма з’явиться), і клікніть на Логотип (повернення на /). Екран НЕ ПОВИНЕН кліпати (біліти)!git add . та git commit -m "Configure React Router dom with Home and Checkout pages".main.Додаток здобув багаторівневу структуру. Завдяки React Router ми “симулюємо” перехід по багатосторінковому сайту, хоча фізично користувач не завантажував жодного нового HTML-файлу з сервера (суть підходу SPA - Single Page Application).
<Link to="..."> замість стандартного <a href="...">? Що таке “гаряча підміна DOM” (Virtual DOM) під час переходу між сторінками?<App /> у <BrowserRouter> всередині файлу main.jsx? Звідки Router дізнається поточний шлях?<Routes> усередині App.jsx і навіщо ми ставимо <Header /> ВИЩЕ від <Routes> (на одному рівні з ним)?<Route path="*" />. Для чого слугує зірочка?react-router-dom, щоб працювала стандартна конфігурація з переліку маршрутів.