Компонент FormattedList

FormatJS предоставляет набор инструментов для интернационализации приложений, и компонент FormattedList является специализированным решением для корректного форматирования списков в соответствии с правилами локали. В отличие от ручной конкатенации строк, компонент использует Intl.ListFormat, обеспечивая грамматически и стилистически правильное отображение элементов списка в разных языках.

Основная задача компонента — преобразование массива значений в локализованное строковое представление списка с учётом:

  • правил пунктуации конкретного языка;
  • типов связок между элементами;
  • особенностей оформления единиц измерения или перечислений.

Компонент устраняет необходимость ручной обработки разделителей (", ", " and ", " или "), делая вывод адаптивным к текущей локали.

Типы списков

FormattedList поддерживает три ключевых режима форматирования, соответствующих спецификации Intl.ListFormat.

conjunction

Используется для перечислений, где элементы объединяются логически:

  • английский: A, B, and C
  • русский: A, B и C

Применяется в описании наборов, групп и коллекций.

disjunction

Используется для альтернатив:

  • английский: A, B, or C
  • русский: A, B или C

Применяется в случаях выбора или взаимоисключающих вариантов.

unit

Используется для единиц измерения и технических данных:

  • 5 meters, 3 centimeters
  • 2 hours 30 minutes

В этом режиме учитываются особенности форматирования единиц в конкретной локали.

Использование в React

Компонент применяется внутри React-приложений как декларативная обёртка над списком значений.

Базовый пример

import { FormattedList } from "react-intl";

const items = ["яблоки", "бананы", "апельсины"];

<FormattedList
  value={items}
  type="conjunction"
/>;

Результат зависит от локали:

  • ru: яблоки, бананы и апельсины
  • en: apples, bananas, and oranges

Входные данные (prop value)

Ключевой параметр — value, представляющий массив строк или React-узлов.

Строковые значения

Наиболее частый вариант:

<FormattedList value={["HTML", "CSS", "JavaScript"]} type="conjunction" />

React-элементы

Поддерживаются компоненты, что позволяет форматировать списки с разметкой:

<FormattedList
  value={[
    <strong key="1">React</strong>,
    <strong key="2">Vue</strong>,
    <strong key="3">Angular</strong>
  ]}
  type="disjunction"
/>

В этом случае форматирование разделителей сохраняется, а элементы остаются интерактивными.

Поведение в зависимости от локали

FormattedList полностью делегирует логику форматирования движку Intl.ListFormat, поэтому поведение определяется текущей локалью IntlProvider.

Примеры различий:

Локаль conjunction disjunction
en A, B, and C A, B, or C
ru A, B и C A, B или C
fr A, B et C A, B ou C

Такая модель исключает необходимость ручного перевода связок.

Внутренняя работа

FormattedList опирается на стандартный API:

new Intl.ListFormat(locale, {
  style: "long",
  type: "conjunction"
});

Далее:

  1. массив передаётся в форматтер;
  2. применяется локаль из контекста IntlProvider;
  3. генерируется строка с корректными разделителями;
  4. результат рендерится как React-узел.

Отличие от ручной сборки строк

Ручная реализация часто выглядит так:

items.join(", ")

Такой подход не учитывает:

  • особенности языка (например, отсутствие союза “and”);
  • различия в порядке слов;
  • правила пунктуации.

FormattedList устраняет эти ограничения, делая вывод корректным для любой поддерживаемой локали.

Форматирование единиц

Режим unit используется для технических данных:

<FormattedList
  value={["10 kg", "250 g", "3 mg"]}
  type="unit"
/>

В некоторых локалях возможны специфические правила объединения единиц, включая сокращения и перестановку элементов.

Производительность

FormattedList не выполняет тяжёлой обработки на уровне JavaScript-логики. Основная работа делегируется нативному Intl.ListFormat, что обеспечивает:

  • минимальные накладные расходы;
  • кэширование локалей в движке;
  • высокую скорость рендеринга даже при больших массивах.

Интеграция с IntlProvider

Компонент работает в контексте провайдера:

import { IntlProvider, FormattedList } from "react-intl";

<IntlProvider locale="ru">
  <FormattedList value={["один", "два", "три"]} type="conjunction" />
</IntlProvider>

Без IntlProvider используется локаль окружения браузера.

Особенности работы с ключами React-элементов

При передаче React-элементов важно соблюдать требования React:

  • каждый элемент должен иметь уникальный key;
  • порядок элементов определяет итоговое форматирование;
  • изменение массива приводит к перерасчёту строки.

Ограничения

  • не поддерживает вложенные списки;
  • не предназначен для сложных грамматических конструкций;
  • зависит от поддержки Intl.ListFormat в окружении;
  • поведение может различаться в старых браузерах без полифиллов.

Совместимость с полифиллами

При отсутствии нативной поддержки используется полифилл intl-listformat, который:

  • эмулирует поведение стандарта;
  • поддерживает основные локали;
  • может иметь ограниченные языковые правила.

Сравнение с другими компонентами FormatJS

  • FormattedMessage — текстовые сообщения с интерполяцией;
  • FormattedNumber — числовое форматирование;
  • FormattedDate — работа с датами;
  • FormattedList — структурирование массивов в человекочитаемые списки.

Каждый компонент решает отдельный слой интернационализации, при этом FormattedList специализируется именно на связях между элементами коллекции.