分岐コンポーネント
翻訳内で条件付きコンテンツに分岐コンポーネントを使う方法
分岐コンポーネントは、<T> コンポーネント内で条件付きコンテンツをレンダリングできるようにします。if/else 文や複数形ルールといった動的ロジックを扱いつつ、すべてのコンテンツのバリエーションが適切に翻訳されることを保証します。
利用可能なコンポーネント
クイックスタート
分岐コンポーネントは、条件ロジックを扱うために <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>
  );
}ブランチコンポーネントの仕組み
ブランチコンポーネントは、翻訳内の条件付きレンダリングを次の方法で解決します。
- <T>内の三項演算子や条件ロジックを置き換える
- 条件が想定どおりの値に一致しない場合にフォールバック用のコンテンツを提供する
- あり得るすべてのコンテンツのバリエーションを翻訳対象にする
- locale の規則に従って複数形ルールを自動で適用する
// ❌ これは動作しません - <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>Variable コンポーネントとの組み合わせ
分岐コンポーネントと Variable コンポーネントは、シームレスに連携します。
<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>不完全な複数形
デフォルトのlocaleに必要な複数形ルールを指定してください:
// ❌ "other" フォームが不足
<Plural
  n={count}
  one={<p>1個のアイテム</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 のドキュメントをご覧ください。
次のステップ
- 文字列翻訳ガイド - JSX を使わずにプレーンテキストを翻訳する
- 動的コンテンツガイド - 実行時の翻訳を処理する
- APIリファレンス:
このガイドはどうでしたか?