Ветвящиеся компоненты

Как использовать ветвящиеся компоненты для условного содержимого в переводах

Ветвящиеся компоненты позволяют условно выводить содержимое внутри компонентов <T>. Они обрабатывают динамическую логику — например, if/else и правила множественного числа — и при этом гарантируют корректную переводимость всех вариантов содержимого.

Доступные компоненты

  • <Branch>: Условное отображение контента на основе значений или состояний
  • <Plural>: Автоматическое согласование по числу по правилам локали

Быстрый старт

Компоненты ветвления работают внутри <T> и обрабатывают условную логику:

import { T, Branch, Plural, Num, Var } from 'gt-react';

function NotificationPanel({ user, messageCount }) {
  return (
    <T>
      <Branch 
        branch={user.status}
        online={<p><Var>{user.name}</Var> сейчас онлайн</p>}
        away={<p><Var>{user.name}</Var> отошёл(ла)</p>}
      >
        <p>Статус пользователя <Var>{user.name}</Var> неизвестен</p>
      </Branch>
      
      <Plural
        n={messageCount}
        one={<p>У вас <Num>{messageCount}</Num> сообщение</p>}
        other={<p>У вас <Num>{messageCount}</Num> сообщений</p>}
      />
    </T>
  );
}

Как работают разветвляющиеся компоненты

Разветвляющиеся компоненты решают задачу условного рендеринга в переводах за счет:

  1. Замены тернарных операторов и условной логики внутри <T>
  2. Предоставления запасного содержимого, когда условия не соответствуют ожидаемым значениям
  3. Возможности перевода всех возможных вариантов содержимого
  4. Автоматического соблюдения правил локали для образования множественного числа
// ❌ Это не работает — условная логика внутри <T>
<T><p>{isActive ? 'Пользователь активен' : 'Пользователь не активен'}</p></T>

// ✅ Это работает — условная логика с ветвлением
<T>
  <Branch 
    branch={isActive} 
    true={<p>Пользователь активен</p>}
    false={<p>Пользователь не активен</p>}
  />
</T>

Руководство по компонентам

<Branch> — условный контент

Используйте <Branch> для любого условного рендеринга на основе значений или состояний:

// Отображение статуса пользователя
<T>
  <Branch 
    branch={user.role}
    admin={<p>Панель администратора</p>}
    user={<p>Панель пользователя</p>}
    guest={<p>Гостевой доступ</p>}
  >
    <p>Уровень доступа неизвестен</p>
  </Branch>
</T>

// Логические условия
<T>
  <Branch 
    branch={isLoggedIn}
    true={<p>С возвращением!</p>}
    false={<p>Войдите в систему</p>}
  />
</T>

// Уровни подписки
<T>
  <Branch
    branch={subscription.tier}
    free={<p>Обновите план, чтобы открыть доступ к премиум‑функциям</p>}
    premium={<p>Наслаждайтесь премиум‑возможностями</p>}
    enterprise={<p>Свяжитесь с поддержкой по корпоративным решениям</p>}
  >
    <p>Статус подписки недоступен</p>
  </Branch>
</T>

<Plural> — интеллектуальные формы множественного числа

Используйте <Plural> для контента, который изменяется в зависимости от количества:

// Базовые формы множественного числа
<T>
  <Plural
    n={itemCount}
    one={<p><Num>{itemCount}</Num> товар в корзине</p>}
    other={<p><Num>{itemCount}</Num> товаров в корзине</p>}
  />
</T>

// Обработка нулевого значения
<T>
  <Plural
    n={notifications}
    zero={<p>Нет новых уведомлений</p>}
    one={<p><Num>{notifications}</Num> уведомление</p>}
    other={<p><Num>{notifications}</Num> уведомлений</p>}
  />
</T>

// Сложные формы множественного числа (по правилам Unicode CLDR)
<T>
  <Plural
    n={days}
    zero={<p>Срок сегодня</p>}
    one={<p>Срок через <Num>{days}</Num> день</p>}
    few={<p>Срок через <Num>{days}</Num> дня</p>}
    many={<p>Срок через <Num>{days}</Num> дней</p>}
    other={<p>Срок через <Num>{days}</Num> дней</p>}
  />
</T>

Сочетание с вариативными компонентами

Ветвление и вариативные компоненты отлично работают вместе:

<T>
  <Branch
    branch={order.status}
    pending={
      <p>
        Заказ <Var>{order.id}</Var> в ожидании. 
        Итого: <Currency currency="USD">{order.total}</Currency>
      </p>
    }
    shipped={
      <p>
        Заказ <Var>{order.id}</Var> отправлен <DateTime>{order.shippedDate}</DateTime>
      </p>
    }
    delivered={
      <p>Заказ <Var>{order.id}</Var> успешно доставлен</p>
    }
  >
    <p>Статус заказа неизвестен</p>
  </Branch>
</T>

Когда использовать ветвящиеся компоненты

Замените тернарные операторы

Преобразуйте условную логику для использования внутри <T>:

// ❌ В <T> нельзя использовать тернарный оператор
<T>{isActive ? <p>Активный пользователь</p> : <p>Неактивный пользователь</p>}</T>

// ✅ Вместо этого используйте Branch
<T>
  <Branch 
    branch={isActive}
    true={<p>Активный пользователь</p>}
    false={<p>Неактивный пользователь</p>}
  />
</T>

Обработка нескольких условий

Замените инструкции switch или цепочки if/else:

// ❌ Сложная логика с условиями
<T>
  {status === 'loading' ? <p>Загрузка…</p> : 
   status === 'error' ? <p>Ошибка</p> : 
   status === 'success' ? <p>Готово!</p> : 
   <p>Неизвестный статус</p>}
</T>

// ✅ Чистая разветвлённая логика
<T>
  <Branch
    branch={status}
    loading={<p>Загрузка…</p>}
    error={<p>Ошибка</p>}
    success={<p>Готово!</p>}
  >
    <p>Неизвестный статус</p>
  </Branch>
</T>

Правила склонения по числам

Замените ручную обработку форм множественного числа:

// ❌ Ручное склонение по числу
<T>{count === 1 ? <p>1 элемент</p> : <p>{count} элементов</p>}</T>

// ✅ Автоматическое склонение по числу
<T>
  <Plural
    n={count}
    one={<p><Num>{count}</Num> элемент</p>}
    other={<p><Num>{count}</Num> элементов</p>}
  />
</T>

Автономное использование

Ветвящиеся компоненты можно использовать и вне <T> — для чистой логики, без перевода:

// Чистое условное рендеринг
<Branch
  branch={theme}
  dark={<DarkModeIcon />}
  light={<LightModeIcon />}
>
  <DefaultIcon />
</Branch>

// Чистое склонение по числу
<Plural
  n={count}
  one={<SingleItemComponent />}
  other={<MultipleItemsComponent />}
/>

Распространённые проблемы

Отсутствующие ключи ветвления

Всегда указывайте запасной вариант для значений, которые не совпали:

// ❌ Нет резервного варианта для непредвиденных значений
<Branch
  branch={userRole}
  admin={<AdminPanel />}
  user={<UserPanel />}
  // А что, если userRole — «moderator»?
/>

// ✅ Всегда добавляйте резервный вариант
<Branch
  branch={userRole}
  admin={<AdminPanel />}
  user={<UserPanel />}
>
  <DefaultPanel /> {/* Резервный вариант для любого другого значения */}
</Branch>

Неполные формы множественного числа

Укажите необходимые формы множественного числа для локали по умолчанию:

// ❌ Отсутствует форма "other"
<Plural
  n={count}
  one={<p>1 item</p>}
  // А что насчёт 0, 2, 3 и т. д.?
/>

// ✅ Укажите обязательные формы
<Plural
  n={count}
  zero={<p>Нет элементов</p>}
  one={<p>1 элемент</p>}
  other={<p>{count} элементов</p>}
/>

Сложная вложенная логика

Хотя это работает, мы рекомендуем максимально упрощать ветвления и избегать глубокой вложенности:

// ❌ Сложная вложенная логика ветвления
<Branch branch={status}>
  <Branch branch={subStatus}>
    {/* Трудно читать и сопровождать */}
  </Branch>
</Branch>

// ✅ Упростите логику или используйте несколько компонентов
<Branch
  branch={`${status}-${subStatus}`}
  active-online={<ActiveOnline />}
  active-offline={<ActiveOffline />}
  inactive-online={<InactiveOnline />}
>
  <DefaultState />
</Branch>

Подробнее о правилах множественного числа — в документации Unicode CLDR.

Следующие шаги

Насколько полезно это руководство?

Ветвящиеся компоненты