Условный рендеринг Route

Условный рендеринг в 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, что делает обёртку универсальной.

Условный рендеринг на основе параметров URL

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 при редиректах для корректного управления историей навигации.
  • Проверять параметры URL через useParams или состояние через useLocation для более гибкой логики.

Условный рендеринг Route в React Router обеспечивает полный контроль над навигацией и доступом к компонентам, позволяя строить сложные маршрутизируемые приложения с безопасностью и гибкостью отображения.