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

f

Представь: ты пишешь компонент, который должен показывать разные элементы в зависимости от того, авторизован ли пользователь. Если авторизован — приветствие и кнопка выхода. Если нет — форма входа. Без условного рендеринга ты бы плодил кучу вложенных конструкций или складывал всю логику в один гигантский return. Но React даёт элегантные инструменты, чтобы сделать код читаемым и гибким.

Условный рендеринг — это не просто тернарный оператор из учебника. Это подход, который влияет на архитектуру всего приложения: отloading-состояний до роли пользователя. На этой странице разберём, какие техники реально работают в боевых проектах, а не только в песочнице. Ты узнаешь, чем отличается && от тернарника, когда стоит выносить логику в отдельную функцию, и почему switch-case может спасти рефакторинг.

Почему обычный if не работает в JSX

В JSX можно вкладывать только выражения. Конструкция if — это инструкция, а не выражение, поэтому её нельзя просто так поместить внутрь {}. Прямой if внутри return вызовет ошибку синтаксиса. Именно поэтому появились альтернативы: тернарный оператор, логическое И (&&) и отдельные функции, которые решают, что возвращать.

Например, если нужно показать блок только когда условие истинно, используют &&. Если нужно переключаться между двумя вариантами — тернарный оператор. А когда вариантов больше двух, приходит на помощь switch-case или вложенные тернарники. Главное — помнить, что вложенные тернарники делают код нечитаемым, хотя иногда это единственный быстрый вариант.

Как работает оператор &&: когда подходит, а когда нет

Логическое И (&&) возвращает последнее истинное выражение или прерывается на первом ложном. В JSX это работает так: если условие слева от && даёт true, рендерится то, что справа. Если false — ничего не рендерится. Но есть подвох.

Ошибка с нулём — одна из самых частых у новичков. Если в условии стоит items.length && ..., то при length=0 в интерфейсе появится 0. Правильно: {items.length > 0 && }.

Тернарный оператор: баланс между краткостью и читаемостью

Тернарный оператор — это единственное выражение, которое позволяет сделать выбор между двумя вариантами прямо внутри JSX. Он читается как «если условие, то одно, иначе другое». Но что делать, если вариантов три или больше?

Например, статус заказа: новый, в обработке, отправлен, доставлен. Для каждого — своя иконка и цвет. Тернарный оператор вложить можно, но лучше использовать отдельную функцию, которая принимает статус и возвращает готовый JSX. В этом случае код остаётся плоским.

  1. Составь таблицу всех возможных значений пропа.
  2. Для каждого значения напиши свой return внутри функции.
  3. Вызови эту функцию внутри JSX, передав значение пропа.
  4. Добавь дефолтный case для непредусмотренных значений.
  5. Размести функцию вне компонента для переиспользования.
  6. Если значений больше пяти — подумай о дополнительном компоненте.
  7. Не забудь про краевые случаи: undefined, null и пустую строку.

Switch-case в мире React: редко, но метко

Конструкция switch-case в JSX напрямую не работает — это тоже инструкция, не выражение. Однако её можно использовать внутри отдельной функции, которая возвращает нужный элемент. Это удобно, когда логика ветвления сложнее, чем два варианта, и вложенные тернарники становятся нечитаемыми.

Например, роли пользователя: админ, модератор, автор, подписчик. Для каждой роли разный набор функций и интерфейс. switch-case внутри функции getDashboardByRole(role) даёт ровно то, что нужно. Главное — не забыть return после каждого case, иначе код продолжит выполняться.

Когда выносить условную логику в отдельный компонент

Бывает, что условный рендеринг разрастается настолько, что заслоняет основную задачу компонента. Например, в компоненте ProfilePage сначала идёт проверка: загружены ли данные, есть ли ошибка, есть ли у пользователя права на редактирование. Если всё копировать в каждый компонент, получится дублирование.

Лучше вынести такие ветки в отдельные компоненты-обёртки: Loaded, ErrorBoundary, ProtectedRoute. Они содержат только условную логику и рендерят children при выполнении условия. Это делает родительский компонент чистым: он просто объявляет, что должно быть, а обёртки заботятся о том, когда это показывать.

Например, компонент Спиннер, который отображается во время загрузки, а когда данные готовы — заменяется на содержимое. Выносить это в отдельный компонент — правильная практика, потому что спиннер появляется на многих страницах, а логика загрузки всегда одинакова.

Производительность: как условный рендеринг влияет на рендер-цикл

Условный рендеринг не просто решает, что показать. Он сообщает React, что весь дочерний контент внутри каждого условия будет полностью пересоздан при переходе между состояниями. Для маленьких элементов это незаметно, но для крупных форм или списков — может вызвать замедление.

Если в разных ветках условного рендеринга используются разные компоненты с состоянием (например, форма входа и форма регистрации), их внутреннее состояние теряется при переключении. Решение — ключи (key) или использование `useMemo`/`useCallback` для сохранения ссылок. Но чаще проще держать обе формы в одном контейнере и переключать только видимость, оставляя состояние нетронутым.

Кстати, в 2026 году ты можешь смело использовать React 18+ — автоматическая батчинг и оптимизация виртуального DOM делают обычный условный рендеринг ещё быстрее. Но тяжёлые анимации при смене состояний лучше оборачивать в `` с fallback.

Сравнение подходов: когда что выбирать

Каждый подход к условному рендерингу — это компромисс между скоростью написания, читаемостью, производительностью и предсказуемостью. Ниже — шпаргалка для быстрого выбора.

  1. && — для одиночного компонента, который рендерится по условию (например, сообщение об ошибке).
  2. Тернарный оператор — для выбора из двух вариантов (например, кнопка «войти» или «выйти»).
  3. Функция-фабрика — когда условий 3 или 4 (например, статус пользователя).
  4. Switch-case — для ветвления на основе строки или числа (статус заказа).
  5. Обёртка (HOC или компонент-защитник) — когда одно условие повторяется во многих компонентах (загрузка, авторизация).
  6. Объект соответствий — когда много ключей и простых JSX-блоков (иконки статусов).
  7. Прямое отключение через css display:none — для переключения вкладок без потери состояния.

Совет: никогда не начинай рефакторить код, который уже работает, «просто ради красоты». Но если ты видишь, что ветвление мешает добавлять новый функционал или баги возникают на переключениях — вынеси логику отдельно.

Добавлено: 23.04.2026