74.70K
AI
Category: programmingprogramming

EDh8pJ9ieo-wa87meLkF9fsQFhToN4GU

1.

React Router
Роутинг
в React
Как это работает, что и где писать: пошаговая
инструкция с кодом и схемами
myapp.com/products/42

2.

02 / 20 · Основы
Что такое роутинг
Роутинг связывает адрес в браузере с тем, что видит пользователь. В React это делает
библиотека React Router.
Обычный сайт (MPA)
N × HTML
Каждый переход: запрос к серверу и полная
перезагрузка страницы
SPA на React
1 × HTML
Один HTML-файл. React подменяет компоненты по
адресу в URL, без перезагрузки

3.

03 / 20 · Основы
Как это работает
ШАГ 2
ШАГ 1
Клик по Link
Пользователь идёт на
/products/42
Router читает URL
→
Через History API, без
запроса к серверу
→
ШАГ 3
ШАГ 4
Сопоставление
Рендер
Ищет подходящий path
среди ваших Route
→
Показывает нужный
компонент на месте
старого
Страница не перезагружается: URL меняется «изнутри», а React перерисовывает только нужную часть.

4.

04 / 20 · Основы
Три режима React Router
Declarative
Data
Framework
Простой старт
Данные и формы
Целый фреймворк
Маршруты описываются JSXкомпонентами
Маршруты-объекты, loader, action,
обработка ошибок
Сборка, SSR, маршруты по файлам
BrowserRouter + Routes
createBrowserRouter
create-react-router
Разбираем Declarative и Data: этого хватает для большинства SPA на Vite.

5.

05 / 20 · Начало работы
Установка и структура
Терминал
Структура папки
npm create vite@latest my-app
cd my-app
npm i react-router
npm run dev
src/
├─ main.jsx ← BrowserRouter
├─ App.jsx ← Routes
├─ pages/
│ ├─ Home.jsx
│ └─ About.jsx
└─ components/
└─ Layout.jsx
В Vite выберите React. В старых уроках встречается react-router-dom, в версии 7+ всё импортируется из react-router.

6.

06 / 20 · Начало работы
Шаг 1. BrowserRouter
// src/main.jsx
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router";
import App from "./App";
createRoot(document.getElementById("root")).render(
<BrowserRouter>
<App />
</BrowserRouter>
);
Где писать: в main.jsx. BrowserRouter даёт всему приложению доступ к адресу и должен стоять выше любых компонентов с
роутингом.

7.

07 / 20 · Начало работы
Шаг 2. Routes и Route
// src/App.jsx
import { Routes, Route } from "react-router";
import Home from "./pages/Home";
import About from "./pages/About";
export default function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
);
}
Как читать
Routes выбирает один подходящий Route
path — адрес в URL
element — компонент, который покажется

8.

08 / 20 · Начало работы
Link и NavLink
import { Link, NavLink } from "react-router";
<nav>
<Link to="/">Главная</Link>
<NavLink to="/about"
className={({ isActive }) =>
isActive ? "active" : ""}>О нас</NavLink>
</nav>
✗ <a href>
Полная перезагрузка страницы, состояние
потеряно
✓ <Link to>
Мгновенный переход. NavLink ещё и знает,
активна ли ссылка: удобно для меню

9.

09 / 20 · Начало работы
Вложенные маршруты
Layout (всегда на месте)
<Routes>
<Route element={<Layout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
</Route>
</Routes>
Шапка и меню
<Outlet />
Home
About
меняется по URL
Layout рисуется один раз, а Outlet — место, куда React подставляет дочернюю страницу.

10.

10 / 20 · Начало работы
Layout и Outlet
// components/Layout.jsx
import { Outlet, NavLink } from "react-router";
export default function Layout() {
return (
<>
<header>
<NavLink to="/">Главная</NavLink>
<NavLink to="/about">О нас</NavLink>
</header>
<main><Outlet /></main>
</>
);
}
Зачем нужен Layout
Один раз пишем общую обёртку: меню,
шапку, футер.
Outlet — «окно», куда React вставляет
дочернюю страницу.
Страницы остаются чистыми: только свой
контент.

11.

11 / 20 · Практика
Динамические параметры
path="/products/:id"
→
/products/42
→
id = "42"
// App.jsx
<Route path="/products/:id" element={<Product />} />
// Product.jsx
import { useParams } from "react-router";
function Product() {
const { id } = useParams();
return <h1>Товар №{id}</h1>;
}

12.

12 / 20 · Практика
Переход из кода
import { useNavigate } from "react-router";
navigate("/path")
переход на страницу
const navigate = useNavigate();
async function onSubmit() {
await login();
navigate("/dashboard");
}
navigate(-1)
шаг назад по истории
navigate("/", { replace: true })
заменить запись: «Назад» не вернёт сюда
Link для кликов по ссылкам. navigate, когда переход идёт после действия: логин, отправка формы.

13.

13 / 20 · Практика
Query-параметры
import { useSearchParams } from "react-router";
// адрес: /search?q=react&page=2
const [params, setParams] = useSearchParams();
const q = params.get("q"); // "react"
setParams({ q: "router", page: 2 }); // ?q=router&page=2
useParams
useSearchParams
Часть пути /products/:id. Нужна, чтобы открыть конкретную
страницу
После знака ?: поиск, фильтры, номер страницы.
Необязательные

14.

14 / 20 · Практика
Index и страница 404
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
index — страница по умолчанию для родителя
(адрес /)
path="*" — ловит всё, что не совпало: это ваша
ваша 404
about без слеша — в дочерних Route путь
относительный

15.

15 / 20 · Практика
Защищённые маршруты
import { Navigate, Outlet } from "react-router";
function ProtectedRoute() {
const { user } = useAuth(); // ваш контекст авторизации
return user ? <Outlet /> : <Navigate to="/login" replace />;
}
// в списке маршрутов:
<Route element={<ProtectedRoute />}>
<Route path="/profile" element={<Profile />} />
</Route>
/profile
→
есть user?
→
✓ Profile
✗ /login

16.

16 / 20 · Data-режим
Data-режим
import { createBrowserRouter } from "react-router";
import { RouterProvider } from "react-router/dom";
const router = createBrowserRouter([
{ path: "/", element: <Layout />, children: [
{ index: true, element: <Home /> },
{ path: "about", element: <About /> },
]},
]);
createRoot(root).render(<RouterProvider router={router} />);
Вместо BrowserRouter и Routes: маршруты — обычный JS-объект. Роутер создаётся один раз, вне React-дерева.

17.

17 / 20 · Data-режим
Loader: данные до рендера
Клик по Link
→
loader() грузит
данные
→
Данные готовы
{ path: "products/:id", element: <Product />,
loader: async ({ params }) => {
const res = await fetch(`/api/products/${params.id}`);
return res.json();
} }
// в компоненте Product:
const product = useLoaderData();
→
Рендер с данными

18.

18 / 20 · Data-режим
Ленивая загрузка
import { lazy, Suspense } from "react";
const Dashboard = lazy(() => import("./pages/Dashboard"));
<Route path="/dashboard" element={
<Suspense fallback={<p>Загрузка…</p>}>
<Dashboard />
</Suspense>
} />
Сборка делится на части: страница загружается, только когда на неё зашли
main.js · сразу
dashboard.js · по переходу
settings.js · по переходу

19.

19 / 20 · Итоги
Частые ошибки
Нет Router выше
<a href> вместо Link
Забыли Outlet
Хуки и Link работают только внутри
BrowserRouter или RouterProvider
Страница перезагружается, состояние
теряется
В Layout нет Outlet: дочерние страницы не
показываются
Слеш в дочернем пути
Пусто после обновления
Роутер в компоненте
В дочерних Route пишите settings, а не
/settings
На хостинге настройте отдачу index.html
для всех путей (rewrite)
В Data-режиме создавайте router один раз,
вне React-дерева

20.

20 / 20 · Итоги
Шпаргалка
Что
Для чего
Bro wserRo uter
Оборачивает приложение, включает роутинг
Ro utes + Ro ute
Список маршрутов: path → elem ent
Link / N avLink
Ссылки без перезагрузки
O utlet
Место для дочернего маршрута
useParam s / useS earchParam s
Параметры пути и q uery
useN avig ate / N avig ate
Переход из кода и редирект
createBro wserRo uter
D ata- режим: маршруты- объекты и load er
Документация: reactrouter.com
English     Русский Rules