React Router — это библиотека для управления маршрутизацией в
приложениях на React. Она позволяет строить сложные интерфейсы с
динамическими URL, поддерживает вложенные маршруты, защищённые маршруты
и возможность работы с историей браузера. Базовые элементы маршрутизации
включают <BrowserRouter>,
<Routes>, <Route> и
<Link>.
<BrowserRouter> оборачивает всё
приложение и обеспечивает управление историей через HTML5 History API.
Это основной контейнер для всех маршрутов:
import { BrowserRouter } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
{/* Здесь будут маршруты */}
</BrowserRouter>
);
}
<Routes> и
<Route> определяют набор маршрутов и
соответствующих компонентов. Каждому маршруту можно задать путь
(path) и компонент (element):
import { Routes, Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
function AppRoutes() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
);
}
<Link> используется для навигации
между маршрутами без перезагрузки страницы:
import { Link } from 'react-router-dom';
function Navigation() {
return (
<nav>
<Link to="/">Главная</Link>
<Link to="/about">О нас</Link>
</nav>
);
}
Динамические маршруты позволяют передавать параметры через URL. Параметры обозначаются двоеточием в пути маршрута:
<Route path="/user/:id" element={<UserProfile />} />
Для доступа к значению параметра используется хук
useParams:
import { useParams } from 'react-router-dom';
function UserProfile() {
const { id } = useParams();
return <div>Профиль пользователя с ID: {id}</div>;
}
Вложенные маршруты обеспечивают более сложную структуру приложения.
Родительский маршрут может содержать дочерние маршруты через элемент
<Outlet>:
import { Outlet, Route, Routes } from 'react-router-dom';
function Dashboard() {
return (
<div>
<h2>Панель управления</h2>
<Outlet />
</div>
);
}
function AppRoutes() {
return (
<Routes>
<Route path="dashboard" element={<Dashboard />}>
<Route path="stats" element={<Stats />} />
<Route path="settings" element={<Settings />} />
</Route>
</Routes>
);
}
Защищённые маршруты позволяют ограничить доступ к определённым страницам, основываясь на состоянии авторизации. Создаётся компонент-обёртка:
import { Navigate } from 'react-router-dom';
function ProtectedRoute({ isAuth, children }) {
return isAuth ? children : <Navigate to="/login" />;
}
Использование:
<Route
path="/profile"
element={
<ProtectedRoute isAuth={userLoggedIn}>
<Profile />
</ProtectedRoute>
}
/>
Хук useNavigate позволяет изменять маршрут
программно:
import { useNavigate } from 'react-router-dom';
function Login() {
const navigate = useNavigate();
const handleLogin = () => {
// Логика авторизации
navigate('/dashboard');
};
return <button onCl ick={handleLogin}>Войти</button>;
}
Для передачи сложных объектов через URL необходимо их сериализовать. Обычно используют JSON и кодировку URI:
import { useNavigate } from 'react-router-dom';
const user = { id: 1, name: 'Иван', roles: ['admin', 'editor'] };
const serializedUser = encodeURIComponent(JSON.stringify(user));
navigate(`/profile?data=${serializedUser}`);
Для восстановления объекта используется декодирование и парсинг:
import { useLocation } from 'react-router-dom';
function Profile() {
const location = useLocation();
const params = new URLSearchParams(location.search);
const user = JSON.parse(decodeURIComponent(params.get('data')));
return <div>Имя пользователя: {user.name}</div>;
}
Ключевые моменты при сериализации объектов:
encodeURIComponent.decodeURIComponent и
JSON.parse.React Router позволяет сохранять состояние между навигациями через
state в объекте маршрута:
navigate('/profile', { state: { user } });
Доступ к состоянию:
import { useLocation } from 'react-router-dom';
const location = useLocation();
const user = location.state?.user;
Это позволяет передавать объекты напрямую без сериализации в URL, что удобнее для временных данных.
Компоненты <Navigate> и хук
useNavigate позволяют реализовать редиректы и контроль
навигации на основе условий:
if (!user) {
return <Navigate to="/login" replace />;
}
Флаг replace предотвращает добавление новой записи в
историю браузера, что важно для корректной навигации.
Для оптимизации приложения можно загружать компоненты маршрутов лениво:
import { lazy, Suspense } from 'react';
import { Route, Routes } from 'react-router-dom';
const Dashboard = lazy(() => import('./Dashboard'));
function AppRoutes() {
return (
<Suspense fallback={<div>Загрузка...</div>}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</Suspense>
);
}
Это снижает размер начального бандла и ускоряет загрузку страницы.
React Router предоставляет гибкий и мощный инструментарий для организации маршрутов, передачи данных, защиты страниц и оптимизации загрузки компонентов. С правильным подходом к сериализации объектов и управлению состоянием маршрутов можно создавать масштабируемые и отзывчивые приложения на React.