Условный рендеринг
Условный рендеринг — механизм отображения разных UI-элементов в зависимости от состояния или пропсов компонента; в React реализуется через стандартные JavaScript-конструкции внутри JSX.
Зачем нужно
Практически любой реальный UI содержит условный рендеринг: «покажи спиннер если загружается», «покажи сообщение об ошибке если запрос упал», «покажи меню если пользователь авторизован». Знание идиоматических паттернов помогает писать читаемый JSX и избегать распространённых ловушек (рендеринг числа 0).
Где используется
- Loading states:
isLoading && <Spinner /> - Error states:
error ? <ErrorMessage /> : <Content /> - Авторизация:
user ? <Dashboard /> : <Login /> - Условные секции, кнопки, бейджи
Паттерны условного рендеринга
function UserProfile({ user, isLoading, error }) {
// 1. Ранний возврат (early return) — для крупных ветвей
if (isLoading) return <Spinner />;
if (error) return <ErrorMessage message={error.message} />;
if (!user) return <EmptyState />;
// Основной рендер только когда данные есть
return (
<div className="profile">
<h1>{user.name}</h1>
{/* 2. Тернарный оператор — два взаимоисключающих варианта */}
{user.isPremium
? <PremiumBadge />
: <UpgradeButton />
}
{/* 3. Логическое И (&&) — показать или ничего */}
{user.isAdmin && <AdminPanel />}
{/* 4. Нуллиш оператор ?? — fallback для null/undefined */}
<p>{user.bio ?? 'Биография не указана'}</p>
{/* 5. Переменная с JSX — для сложных условий */}
{renderActions(user)}
</div>
);
}
// 5. Вынесение условной логики в переменную
function renderActions(user) {
if (user.isBlocked) {
return <span className="blocked">Заблокирован</span>;
}
if (user.isPending) {
return <span className="pending">На проверке</span>;
}
return (
<div className="actions">
<button>Написать</button>
<button>Подписаться</button>
</div>
);
}
switch/object map — для множества вариантов
// Много вариантов → switch или объект вместо цепочки if/else
const STATUS_COMPONENTS = {
loading: <Spinner />,
error: <ErrorIcon />,
success: <CheckIcon />,
idle: null,
};
function StatusIndicator({ status }) {
// Объект-маппинг чище цепочки тернарников
return STATUS_COMPONENTS[status] || null;
}
// Или компонент-переключатель
function OrderStatus({ status }) {
switch (status) {
case 'pending': return <Badge color="yellow">Ожидает</Badge>;
case 'shipped': return <Badge color="blue">Отправлен</Badge>;
case 'delivered': return <Badge color="green">Доставлен</Badge>;
case 'cancelled': return <Badge color="red">Отменён</Badge>;
default: return null;
}
}
Условный рендеринг и CSS
// Для частых переключений: скрывать через CSS, не размонтировать
// (сохраняет state, избегает анимаций)
function Drawer({ isOpen, children }) {
return (
<div
className={`drawer ${isOpen ? 'drawer--open' : 'drawer--closed'}`}
// aria-hidden важен для доступности
aria-hidden={!isOpen}
>
{children}
</div>
);
}
// Для редких переключений: размонтирование экономит память
function Modal({ isOpen, children }) {
if (!isOpen) return null; // компонент размонтируется, state сбрасывается
return <div className="modal">{children}</div>;
}
Частые ошибки
{count && <Component />}рендерит0— еслиcount === 0, в JSX вставляется число0; используйте{count > 0 && <Component />}или{!!count && <Component />}.- Тернарник для сложных условий — 4+ вложенных тернарника нечитаемы; выносите логику в переменную или компонент.
- Нет обработки
null/undefined—{user.name}без проверки выбрасывает ошибку еслиuserне загружен; используйте optional chaining{user?.name}.
Связанные темы
- _MOC SPA
- Компонент -- что это такое
- State -- внутреннее состояние
- Загрузка данных и loading states
- Списки и ключи (keys)