# General Translation Knowledge Base: React で複数形を扱うにはどうすればよいですか？
URL: https://generaltranslation.com/ja/kb/how-to-handle-plurals-in-react.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: React で複数形を扱うには、各言語の複数形ごとに文を 1 つずつ用意し、その言語の複数形規則に従って選択します。英語の複数形は 2 種類ですが、ロシア語は 4 種類、アラビア語は 6 種類あるためです。gt-react と gt-next に含まれる General Translation の `<Plural>` コンポーネントに翻訳元の形を渡せば、各対象言語に必要な形は General Translation が生成します。
Category: ロケール別フォーマット
Last updated: 2026-10-21
Authors: Archie McKenzie
Published: 2025-02-17

React で複数形を扱うには、各言語の複数形ごとに文を 1 つずつ用意し、その言語の複数形規則に従って数値ごとに適切な文を選択します。この選択は JavaScript 組み込みの [`Intl.PluralRules`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules) が行います。これは、数値を Unicode CLDR (Common Locale Data Repository) で定義された複数形カテゴリに対応付けるものです。カテゴリ数は、英語が 2、ロシア語とポーランド語が 4、アラビア語が 6、日本語が 1 です。

`count === 1` による判定は英語にしか通用しません。ロシア語では整数に対して「1 файл」「2 файла」「5 файлов」 (1 ファイル、2 ファイル、5 ファイル) の 3 つの形を使い分け、21 は 1 と同じ形をとります。1 のときは「файл」、それ以外はすべて「файлов」と表示する判定では、「2 файлов」や「21 файлов」とレンダリングされてしまいますが、これはどちらも誤りです。

## Video

The video is narrated in English, with English captions.

[How do I handle plurals in React?](https://caxecubb9c64cezv.public.blob.vercel-storage.com/films/kb-how-to-handle-plurals-in-react.mp4) (48 秒)

General Translation handles plurals in React with the `Plural` component. Run `npx gt init` and sign in, give `Plural` the count and an English sentence for each form, wrap it in a `T` component with the count in `Num`, then run `npx gt translate` to write the forms each language needs.

## 各言語の複数形カテゴリとは？

CLDR では 6 つの複数形カテゴリ (`zero`、`one`、`two`、`few`、`many`、`other`) が定義されています。各言語はその部分集合を使用し、言語ごとの規則によって、すべての数値がその部分集合内のいずれか 1 つのカテゴリに割り当てられます。

| 言語      | カテゴリ                                         | 各カテゴリに該当する数                                                                  |
| ------- | -------------------------------------------- | ---------------------------------------------------------------------------- |
| 英語      | `one`, `other`                               | 1 は `one`、0・2・5・1.5 は `other`                                                |
| 日本語、中国語 | `other`                                      | すべての数が `other`                                                               |
| ロシア語    | `one`, `few`, `many`, `other`                | 1・21・101 は `one`、2〜4 と 22 は `few`、0・5〜20・100 は `many`、1.5 は `other`          |
| ポーランド語  | `one`, `few`, `many`, `other`                | 1 は `one`、2〜4 と 22 は `few`、0・5〜21・100 は `many`、1.5 は `other`                 |
| アラビア語   | `zero`, `one`, `two`, `few`, `many`, `other` | 0 は `zero`、1 は `one`、2 は `two`、3〜10 は `few`、11〜99 は `many`、100〜102 は `other` |

ある言語のカテゴリ一覧を確認するには、ブラウザのコンソールで `new Intl.PluralRules('ru').resolvedOptions().pluralCategories` を実行します。ロシア語の場合は `one`、`few`、`many`、`other` が返されます。

## 多言語対応の React アプリで複数形を扱うにはどうすればよいですか？

General Translation では、React の複数形を `gt-react` (Next.js では `gt-next`) の [`<Plural>`](/docs/react/reference/components/plural) コンポーネントで扱います。ソース言語で使う形を記述するだけで、各対象言語に必要な形は General Translation が生成します。

1. [`<Plural>`](/docs/react/reference/components/plural) に数値を `n` として渡し、ソース言語の各形に対応するプロパティを指定します (英語なら `one` と `other` など) 。
2. 数値を [`<Num>`](/docs/react/reference/components/num) でラップし、[`<Plural>`](/docs/react/reference/components/plural) 全体を [`<T>`](/docs/react/reference/components/t) でラップします。こうすることで、各形が数値を変数として含む完全な文として翻訳されます。
3. 本番環境向けのビルド前に [`npx gt translate`](/docs/cli/reference/commands/translate) を実行します。General Translation が各形を翻訳し、各対象言語で使われるカテゴリを追加します。たとえば、アラビア語では 6 つ、ロシア語では 4 つの形が生成されます。

```tsx
import { T, Plural, Num } from 'gt-react';

export function InboxCount({ count }: { count: number }) {
  return (
    <T>
      <Plural
        n={count}
        one={<>You have <Num>{count}</Num> message.</>}
        other={<>You have <Num>{count}</Num> messages.</>}
      />
    </T>
  );
}
```

レンダリング時、General Translation の [`<Plural>`](/docs/react/reference/components/plural) は、アクティブなロケールの [CLDR 複数形規則](https://cldr.unicode.org/index/cldr-spec/plural-rules)に従って `count` に対応する形を選択します。該当するカテゴリがない場合は、`plural`、`other`、子要素の順にフォールバックします。[`<Num>`](/docs/react/reference/components/num) は `Intl.NumberFormat` を使ってローカルで数値を書式設定するため、1000000 は英語では 1,000,000、ドイツ語では 1.000.000、ヒンディー語では 10,00,000 とレンダリングされます。この値が General Translation API に送信されることはありません。

文言を変更しても複数形メッセージの翻訳が常に最新の状態に保たれるようにするには、CI で [`npx gt translate`](/docs/cli/reference/commands/translate) を実行します。または、General Translation の AI エージェントである [Locadex を設定](/docs/platform/locadex/guides/configuring-automations)し、プルリクエストの変更時やコミットのプッシュ時に新しいソースコンテンツが翻訳されるようにします。生成された形は、レビュアーが General Translation のダッシュボードにある[翻訳エディター](/docs/platform/dashboard/guides/reviewing-translations)で修正できます。React、Next.js、および実験的な `gt-tanstack-start` と `gt-react-native` での手順については、[複数形と分岐の扱い](/docs/react/guides/handling-plurals-and-branches)を参照してください。

## 英語のみの React アプリで文字列を複数形にするには？

英語のみで提供するアプリに必要なのは `one` と `other` の 2 つの形式だけなので、小さなヘルパーで十分です。不規則な名詞 (&quot;person&quot; と &quot;people&quot;) や動詞 (&quot;is&quot; と &quot;are&quot;) も数に応じて切り替わるよう、フレーズ全体を渡してください。

```ts title="pluralize.ts"
const englishPlurals = new Intl.PluralRules('en-US');

export function pluralize(count: number, one: string, other: string): string {
  return englishPlurals.select(count) === 'one' ? one : other;
}
```

```tsx
import { pluralize } from './pluralize';

export function CartSummary({ items, viewers }: { items: number; viewers: number }) {
  return (
    <>
      {/* 1 item、5 items */}
      <p>{pluralize(items, `${items} item`, `${items} items`)}</p>
      {/* 1 person is watching、3 people are watching */}
      <p>{pluralize(viewers, '1 person is watching', `${viewers} people are watching`)}</p>
    </>
  );
}
```

英語の規則では 0 は `other` に分類されるため、このヘルパーは &quot;0 items&quot; とレンダリングします。このヘルパーは英語の規則をハードコードしており、受け取るフレーズも 2 つだけですが、ロシア語では 3 つ必要です。そのため、アプリで 2 つ目の言語に対応する際は、[`<Plural>`](/docs/react/reference/components/plural) または別の国際化 (i18n) ライブラリに置き換えてください。

## JSX の外で文字列を複数形にするには？

`placeholder` や `aria-label` のように、プレーンな文字列である必要があるテキストには、General Translation の [`useGT`](/docs/react/reference/hooks/use-gt) フックを使用します。このフックは、ICU (International Components for Unicode) の複数形メッセージを受け取る関数を返します。メッセージ内の `#` は、その数値に置き換えて出力されます。

```tsx
import { useGT } from 'gt-react';

export function ProductSearch({ count }: { count: number }) {
  const gt = useGT();
  return (
    <input
      type="search"
      placeholder={gt(
        'Search {count, plural, one {# product} other {# products}}',
        { count }
      )}
    />
  );
}
```

非同期 App Router コンポーネントでは、代わりに `gt-next/server` の [`getGT`](/docs/react/nextjs/reference/functions/get-gt) を使用してください。文字列 API のその他の機能については、[文字列の翻訳](/docs/react/guides/translating-strings)をご覧ください。

## react-i18next と react-intl は複数形をどのように扱うのか？

どちらのライブラリも CLDR の複数形規則に従ってカテゴリを選び、各言語の文をカタログファイルから読み込みます。つまり、すべてのメッセージについて、すべての言語のすべての形をチームや翻訳者が自分で書く必要があります。翻訳を生成する機能はどちらのライブラリにもありません。

[react-i18next](https://react.i18next.com/) は、カテゴリごとに、カテゴリ名をサフィックスとして付けたキーを 1 つずつ保存し、`count` オプションの値に応じてキーを選択します。

```json title="locales/en/translation.json"
{
  "messages_one": "You have {{count}} message.",
  "messages_other": "You have {{count}} messages."
}
```

```tsx
import { useTranslation } from 'react-i18next';

export function InboxCount({ count }: { count: number }) {
  const { t } = useTranslation();
  return <p>{t('messages', { count })}</p>;
}
```

アラビア語のファイルには、`messages_zero` から `messages_other` までの6つのキーが必要です。すべてのサフィックスは [i18next の複数形ドキュメント](https://www.i18next.com/translation-function/plurals)に記載されています。

FormatJS の React ライブラリである [react-intl](https://formatjs.github.io/docs/react-intl/) では、すべてのカテゴリを1つのICU MessageFormat文字列にまとめて記述します。この中の `#` は、ロケールに応じて書式設定された数値を表します。

```tsx
import { FormattedMessage } from 'react-intl';

export function InboxCount({ count }: { count: number }) {
  return (
    <FormattedMessage
      id="inbox.count"
      defaultMessage="{count, plural, one {You have # message.} other {You have # messages.}}"
      values={{ count }}
    />
  );
}
```

アラビア語のカタログでは、`zero`、`one`、`two`、`few`、`many`、`other` の各分岐ごとにメッセージを記述する必要があります。複数形の分岐や `=0` のような完全一致については、[FormatJS の ICU 構文ガイド](https://formatjs.github.io/docs/core-concepts/icu-syntax/)で解説されています。

## React で複数形を扱うには、どの方法を使うべきか？

| 方法                                                                          | 各形式の記述場所                    | 各対象言語の形式を書く担当者                                                                           |
| --------------------------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------------------- |
| `Intl.PluralRules` ヘルパー                                                     | コード内 (英語のみ)                 | 不要 (アプリは単一言語で提供されるため)                                                                    |
| react-i18next                                                               | 言語ごとの JSON ファイル内のサフィックス付きキー | 自チームまたは翻訳者                                                                               |
| react-intl                                                                  | 言語ごとのカタログ内の ICU メッセージ       | 自チームまたは翻訳者                                                                               |
| General Translation の [`<Plural>`](/docs/react/reference/components/plural) | JSX 内のソース言語の形式              | General Translation ([`npx gt translate`](/docs/cli/reference/commands/translate) の実行時)  |

アプリを英語のみで提供する場合は、ヘルパーを使用してください。チームですでにカタログファイルを管理しており、翻訳者がすべての形式を手作業で書いている場合は、react-i18next または react-intl を単体で使用してください。アプリを複数の言語で提供し、リリースごとに文言が変わる場合は、General Translation の [`<Plural>`](/docs/react/reference/components/plural) を使用してください。新しい複数形メッセージを追加するたびに、General Translation がすべての対象言語の形式を生成します。

## よくある質問

### 件数が 0 のときに「No items」と表示するには？

英語のルールでは 0 は `other` に分類されるため、`one` と `other` だけを持つメッセージでは「0 items」と表示されます。文字列の場合は、[`useGT`](/docs/react/reference/hooks/use-gt) に渡す ICU メッセージに、0 に完全一致するケースを追加します。

```tsx
gt('{count, plural, =0 {No items} one {# item} other {# items}}', { count });
```

JSX では `count === 0` かどうかを判定し、空の状態は別の [`<T>`](/docs/react/reference/components/t) ブロックでレンダリングします。

### Plural コンポーネントは Next.js で使えますか？

はい。[`<Plural>`](/docs/react/reference/components/plural)、[`<T>`](/docs/react/reference/components/t)、[`<Num>`](/docs/react/reference/components/num) を `gt-next` からインポートしてください。props は `gt-react` と同じです。これらのコンポーネントは、実験的な `gt-tanstack-start` と `gt-react-native` でも General Translation から提供されています。

### 複数形はどの数値でテストすればよいですか？

各複数形メッセージを、すべての対象ロケールで 0、1、2、5、11、21、100 の各数値を使ってレンダリングしてください。これらの数値で、英語、ロシア語、ポーランド語、アラビア語における整数のカテゴリをすべて網羅できます。さらに 1.5 を加えると、ロシア語とポーランド語の `other` も確認できます。

## Related questions

- [JSX の条件付きテキストはどのように翻訳すればよいですか？](https://generaltranslation.com/ja/kb/translate-conditional-jsx.mdx): 文を分割せずに、すべてのバージョンを翻訳します。三項演算子を使うと文が断片に分かれ、断片は意味を失ううえ、各言語の語順に沿った位置にも置けなくなります。General Translation では `<T>` の中で `<Branch>` を使い、文をひとつの単位として翻訳します。
- [翻訳ファイルなしでi18nは実現できますか？](https://generaltranslation.com/ja/kb/i18n-without-translation-files.mdx): はい。General Translationの gt-react と gt-next ライブラリを使えば、翻訳キーも、言語ごとに管理するJSONファイルもなしで、ReactとNext.jsのi18nを実現できます。文言は `<T>` コンポーネント内のJSXにインラインで記述したままで、gt translate コマンドがコードから得た文脈をもとに、ビルド時に各言語の翻訳を生成します。さらにLocadexを使えば、プルリクエストを通じて翻訳を常に最新の状態に保てます。
- [Reactアプリに最適なi18nライブラリは？](https://generaltranslation.com/ja/kb/best-react-i18n-library.mdx): React向けの主要なi18nライブラリは、General Translationのgt-react、react-i18next、Lingui、React Intlの4つです。いずれも翻訳のレンダリングと書式設定に対応していますが、JSXにインラインで記述したテキストから翻訳の生成まで行えるのはgt-reactだけです。i18nextのカタログやプラグインを引き続き使いたい場合はreact-i18next、メッセージを抽出してコンパイル済みカタログを生成したい場合はLingui、FormatJSとICU MessageFormatを使いたい場合はReact Intlを選びましょう。

## Previous and next questions

- Next question: [JSX の条件付きテキストはどのように翻訳すればよいですか？](https://generaltranslation.com/ja/kb/translate-conditional-jsx.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/ja/kb/sitemap.md) for every article.
