Условный рендеринг в React Router позволяет управлять отображением компонентов в зависимости от состояния приложения, параметров URL или других условий. В отличие от простого указания компонента для маршрута, условный рендеринг предоставляет гибкость при реализации логики доступа, редиректов и динамической загрузки содержимого.
element с тернарным операторомВ React Router v6 компонент Route больше не принимает
проп component или render. Вместо этого
используется проп element, которому передаётся JSX. Это
позволяет применять условные конструкции прямо в JSX.
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import Home from './Home';
import Login from './Login';
const isAuthenticated = false;
function App() {
return (
<Router>
<Routes>
<Route
path="/"
element={isAuthenticated ? <Home /> : <Navigate to="/login" />}
/>
<Route path="/login" element={<Login />} />
</Routes>
</Router>
);
}
В примере выше при попытке открыть корневой путь /
выполняется проверка состояния isAuthenticated. Если
пользователь не авторизован, происходит редирект на страницу логина.
Для упрощения повторного использования условной логики часто создают
компонент-обёртку ProtectedRoute. Такой подход позволяет
избежать дублирования кода.
function ProtectedRoute({ isAllowed, redirectPath = '/login', children }) {
if (!isAllowed) {
return <Navigate to={redirectPath} replace />;
}
return children;
}
// Использование
<Routes>
<Route
path="/dashboard"
element={
<ProtectedRoute isAllowed={isAuthenticated}>
<Dashboard />
</ProtectedRoute>
}
/>
</Routes>
Особенности:
replace предотвращает добавление редиректа в историю
браузера, что делает навигацию более предсказуемой.children позволяет передавать любой JSX, что делает
обёртку универсальной.React Router позволяет извлекать параметры маршрута с помощью хука
useParams. Это удобно для рендеринга контента, который
зависит от динамических сегментов URL.
import { useParams } from 'react-router-dom';
function UserProfile() {
const { userId } = useParams();
return (
<div>
{userId ? (
<p>Профиль пользователя с ID: {userId}</p>
) : (
<p>Пользователь не найден</p>
)}
</div>
);
}
// Маршрут
<Route path="/user/:userId" element={<UserProfile />} />
Важно: условие проверяет наличие параметра и позволяет динамически изменять отображаемое содержимое без перенаправления.
React Router поддерживает вложенные маршруты. При условном рендеринге можно комбинировать защиту маршрутов и подмаршруты.
<Routes>
<Route path="/app" element={<ProtectedRoute isAllowed={isAuthenticated}><AppLayout /></ProtectedRoute>}>
<Route path="profile" element={<Profile />} />
<Route path="settings" element={<Settings />} />
</Route>
</Routes>
Здесь AppLayout будет рендериться только для
авторизованных пользователей, а подмаршруты profile и
settings наследуют это условие.
Outlet для вложенных маршрутовOutlet используется как точка рендеринга для дочерних
маршрутов внутри родительского компонента. В комбинации с условным
рендерингом можно полностью контролировать доступ к различным разделам
приложения.
import { Outlet } from 'react-router-dom';
function AppLayout() {
return (
<div>
<nav>Меню навигации</nav>
<main>
<Outlet />
</main>
</div>
);
}
Рендеринг дочерних маршрутов через Outlet происходит
только после проверки условий в родительском
ProtectedRoute.
NavigateКомпонент Navigate позволяет не только редиректить
пользователя, но и интегрировать условный рендеринг напрямую в маршруты
без использования обёрток.
<Route
path="/premium"
element={isPremiumUser ? <PremiumContent /> : <Navigate to="/upgrade" />}
/>
Здесь доступ к премиум-контенту полностью контролируется логикой условия.
ProtectedRoute, RoleRoute) для повторяющихся
условий.replace при редиректах для корректного
управления историей навигации.useParams или состояние
через useLocation для более гибкой логики.Условный рендеринг Route в React Router обеспечивает полный контроль над навигацией и доступом к компонентам, позволяя строить сложные маршрутизируемые приложения с безопасностью и гибкостью отображения.