# General Translation Knowledge Base: Как работать с формами множественного числа в React?
URL: https://generaltranslation.com/ru/kb/how-to-handle-plurals-in-react.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Чтобы работать с формами множественного числа в React, задайте для каждого языка по одному предложению на каждую форму множественного числа и выбирайте нужное по правилам множественного числа этого языка — ведь в английском 2 формы, в русском 4, а в арабском 6. Компонент `<Plural>` от General Translation в gt-react и gt-next принимает формы на исходном языке, а General Translation генерирует формы, нужные каждому языку перевода.
Category: Форматирование с учётом локали
Last updated: 2026-10-21
Authors: Archie McKenzie
Published: 2025-02-17

Чтобы работать с формами множественного числа в React, задайте для каждого языка по одному предложению на каждую форму множественного числа и выбирайте нужное предложение для каждого числа по правилам множественного числа этого языка. Выбором занимается встроенный в 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 файлов», причём 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 определяет шесть категорий множественного числа: `zero`, `one`, `two`, `few`, `many` и `other`. Каждый язык использует лишь их подмножество, а правила языка относят любое число к одной из категорий этого подмножества.

| Язык                | Категории                                    | Какие числа относятся к каждой категории                                                            |
| ------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Английский          | `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 с помощью компонента [`<Plural>`](/docs/react/reference/components/plural) из `gt-react` (или `gt-next` в Next.js). Вы указываете формы, которые есть в языке-источнике, а 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 переведёт каждую форму и добавит категории, которые используются в каждом языке перевода: например, для арабского получится шесть форм, а для русского — четыре.

```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>
  );
}
```

При рендеринге компонент [`<Plural>`](/docs/react/reference/components/plural) от General Translation выбирает форму для `count` по [правилам множественного числа CLDR](https://cldr.unicode.org/index/cldr-spec/plural-rules) активной локали. Если нужной категории нет, используется `plural`, затем `other`, а затем дочерние элементы. [`<Num>`](/docs/react/reference/components/num) форматирует число локально с помощью `Intl.NumberFormat`: 1000000 отображается как 1,000,000 на английском, 1.000.000 на немецком и 10,00,000 на хинди, а само значение никогда не отправляется в API General Translation.

Чтобы сообщения с формами множественного числа не теряли перевод при изменении текста, запускайте [`npx gt translate`](/docs/cli/reference/commands/translate) в CI или [настройте Locadex](/docs/platform/locadex/guides/configuring-automations) — AI-агент General Translation — на перевод нового исходного содержимого при изменении пул-реквеста или пуше коммита. Рецензенты могут исправить любую сгенерированную форму в [Редакторе переводов](/docs/platform/dashboard/guides/reviewing-translations) на панели управления General Translation. Пошаговые инструкции для React, Next.js, а также экспериментальных `gt-tanstack-start` и `gt-react-native` приведены в руководстве [Обработка форм множественного числа и ветвей](/docs/react/guides/handling-plurals-and-branches).

## Как добавить формы множественного числа для строки в React-приложении, которое работает только на английском?

Приложению, которое поддерживает только английский язык, нужны всего две формы — `one` и `other`, поэтому хватит небольшой вспомогательной функции. Передавайте фразы целиком, чтобы неправильные существительные (&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 товар, 5 товаров */}
      <p>{pluralize(items, `${items} item`, `${items} items`)}</p>
      {/* 1 человек смотрит, 3 человека смотрят */}
      <p>{pluralize(viewers, '1 person is watching', `${viewers} people are watching`)}</p>
    </>
  );
}
```

По правилам английского языка 0 относится к категории `other`, поэтому вспомогательная функция выводит &quot;0 items&quot;. Эта функция жёстко закладывает английские правила и принимает две формы фразы, а для русского языка нужны три. Поэтому, когда в приложении появится второй язык, замените её на [`<Plural>`](/docs/react/reference/components/plural) или другую библиотеку интернационализации (i18n).

## Как задать форму множественного числа для строки вне JSX?

Если текст должен быть обычной строкой — например, `placeholder` или `aria-label`, — используйте хук [`useGT`](/docs/react/reference/hooks/use-gt) от General Translation. Он возвращает функцию, которая принимает сообщение с формами множественного числа в формате 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 используйте вместо этого [`getGT`](/docs/react/nextjs/reference/functions/get-gt) из `gt-next/server`. Остальные возможности API для работы со строками описаны в разделе [Перевод строк](/docs/react/guides/translating-strings).

## Как react-i18next и react-intl работают с формами множественного числа?

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

[react-i18next](https://react.i18next.com/) хранит отдельный ключ для каждой категории (категория добавляется к ключу в виде суффикса) и выбирает нужный ключ по опции `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`. Все суффиксы перечислены в [документации i18next по формам множественного числа](https://www.i18next.com/translation-function/plurals).

[react-intl](https://formatjs.github.io/docs/react-intl/), React-библиотека от FormatJS, описывает все категории в одной строке 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-сообщения, по одному каталогу на каждый язык        | Ваша команда или переводчики                                                                 |
| [`<Plural>`](/docs/react/reference/components/plural) от General Translation | Формы на исходном языке, прямо в JSX                    | General Translation при запуске [`npx gt translate`](/docs/cli/reference/commands/translate) |

Если приложение выпускается только на английском, используйте вспомогательную функцию. Если ваша команда уже ведёт файлы каталогов, а переводчики вручную пишут каждую форму, достаточно react-i18next или react-intl. Если же приложение выпускается на нескольких языках, а тексты меняются с каждым релизом, используйте [`<Plural>`](/docs/react/reference/components/plural) от General Translation: для каждого нового сообщения с формами множественного числа General Translation сам создаёт формы на всех языках перевода.

## Часто задаваемые вопросы

### Как вывести «No items», если количество равно 0?

По правилам английского языка 0 относится к категории `other`, поэтому сообщение только с `one` и `other` выведет «0 items». Если вы работаете со строкой, добавьте точное совпадение для нуля в ICU-сообщение, которое передаёте в [`useGT`](/docs/react/reference/hooks/use-gt):

```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` — они принимают те же пропсы, что и в `gt-react`. Эти компоненты также входят в экспериментальный пакет `gt-tanstack-start` и в `gt-react-native`.

### На каких числах проверять формы множественного числа?

Выполните рендеринг каждого сообщения с формами множественного числа для значений 0, 1, 2, 5, 11, 21 и 100 в каждой целевой локали. Эти значения охватывают все категории целых чисел в английском, русском, польском и арабском языках. Чтобы проверить категорию `other` в русском и польском, добавьте значение 1.5.

## Related questions

- [Как перевести условный текст в JSX?](https://generaltranslation.com/ru/kb/translate-conditional-jsx.mdx): Не разбивайте предложение и переводите каждый его вариант целиком, ведь тернарный оператор дробит его на фрагменты, которые теряют смысл и своё место в порядке слов каждого языка. В General Translation для этого используется `<Branch>` внутри `<T>`, который переводит предложение как единое целое.
- [Можно ли делать i18n без файлов перевода?](https://generaltranslation.com/ru/kb/i18n-without-translation-files.mdx): Да. Библиотеки gt-react и gt-next от General Translation обеспечивают i18n для React и Next.js без ключей перевода и без отдельного JSON-файла для каждого языка, который приходится поддерживать. Тексты остаются встроенными в JSX внутри компонента `<T>`, а команда gt translate генерирует переводы для каждого языка во время сборки, учитывая контекст из вашего кода. Locadex может поддерживать их в актуальном состоянии через пул-реквесты.
- [Какая библиотека интернационализации лучше всего подходит для приложения React?](https://generaltranslation.com/ru/kb/best-react-i18n-library.mdx): Четыре основные библиотеки интернационализации для React — это gt-react от General Translation, react-i18next, Lingui и React Intl. Все четыре выполняют рендеринг и форматирование переводов, но только gt-react ещё и генерирует их — на основе текста, написанного прямо в JSX. Выбирайте react-i18next, если хотите сохранить каталоги и плагины i18next, Lingui — если нужно извлечение текста в скомпилированные каталоги, а React Intl — если вам нужны FormatJS и ICU MessageFormat.

## Previous and next questions

- Next question: [Как перевести условный текст в JSX?](https://generaltranslation.com/ru/kb/translate-conditional-jsx.mdx)

## Sitemap

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