Компоненты FormattedMessage, FormattedNumber

FormatJS представляет собой экосистему для интернационализации JavaScript-приложений, основанную на ICU MessageFormat. В React-части библиотеки ключевую роль играют компоненты отображения локализованных сообщений и значений, среди которых особое значение имеют FormattedMessage и FormattedNumber.

FormattedMessage является декларативным компонентом для вывода локализованных строк, поддерживающих интерполяцию, склонения, множественные формы и вложенные структуры. Он интегрируется с системой сообщений ICU и использует контекст intl, предоставляемый провайдером интернационализации.

Базовая модель сообщения

Сообщения задаются в формате ICU:

{
  "greeting": "Привет, {name}!"
}

Использование компонента:

<FormattedMessage id="greeting" values={{ name: "Алексей" }} />

Механизм работы заключается в поиске строки по id, последующем разборе шаблона и подстановке значений через values.

Основные свойства FormattedMessage

id

Уникальный идентификатор сообщения в словаре локализации. Используется для извлечения строки из набора переводов.

defaultMessage

Fallback-строка, применяемая при отсутствии перевода для текущей локали.

<FormattedMessage
  id="welcome.text"
  defaultMessage="Welcome, {name}"
  values={{ name: "User" }}
/>

values

Объект подстановок, содержащий переменные, используемые внутри ICU-строки. Может включать строки, числа, даты или даже React-элементы.

Интерполяция значений

ICU MessageFormat поддерживает динамическую подстановку:

{
  "items": "У пользователя {count} сообщений"
}
<FormattedMessage id="items" values={{ count: 5 }} />

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

Плюрализация

ICU поддерживает сложные правила множественных форм:

{
  "notifications": "У пользователя {count, plural, one {# уведомление} few {# уведомления} many {# уведомлений} other {# уведомления}}"
}
<FormattedMessage id="notifications" values={{ count: 3 }} />

Система автоматически применяет правила выбранного языка, включая языки со сложной морфологией.

Вложенные компоненты и rich-text форматирование

FormattedMessage поддерживает вставку React-элементов через values:

<FormattedMessage
  id="terms"
  defaultMessage="Согласие с <link>условиями</link>"
  values={{
    link: (chunks) => <a href="/terms">{chunks}</a>
  }}
/>

Такой механизм позволяет безопасно внедрять интерактивные элементы в локализованные строки без ручной конкатенации HTML.

Работа с форматами данных внутри сообщений

values может содержать не только строки, но и числовые или датовые значения, которые автоматически форматируются через intl API при использовании соответствующих функций:

<FormattedMessage
  id="balance"
  defaultMessage="Баланс: {value, number, currency}"
  values={{ value: 1250.5 }}
/>

FormattedNumber: форматирование чисел

FormattedNumber отвечает за локализованное представление числовых значений с использованием Intl.NumberFormat. Он позволяет учитывать региональные особенности отображения чисел, включая разделители, валюты, проценты и единицы измерения.

Базовое использование

<FormattedNumber value={1000} />

Результат зависит от текущей локали: формат разделителей, пробелов и запятых изменяется автоматически.

Основные режимы форматирования

Валюты

<FormattedNumber value={99.99} style="currency" currency="USD" />

Ключевой параметр currency определяет тип валюты. Форматирование включает символ валюты и локальные правила его размещения.

Проценты

<FormattedNumber value={0.42} style="percent" />

Значение интерпретируется как доля от 1 и преобразуется в процентное отображение.

Единицы измерения

<FormattedNumber value={15} style="unit" unit="kilometer" />

Используется для отображения физических величин с учётом локальных соглашений.

Настройка точности

FormattedNumber позволяет управлять точностью отображения:

<FormattedNumber
  value={12.3456}
  minimumFractionDigits={2}
  maximumFractionDigits={3}
/>

Это особенно важно при отображении финансовых данных или результатов вычислений.

Форматы представления чисел

Стандартный числовой формат

Используется по умолчанию и зависит от локали:

<FormattedNumber value={1000000} />

Компактная запись

<FormattedNumber value={1000000} notation="compact" />

Применяется сокращённое отображение вроде «1M» или локализованных аналогов.

Научная нотация

<FormattedNumber value={1234000} notation="scientific" />

Используется в научных и технических интерфейсах.

Локализация чисел

FormattedNumber полностью зависит от текущей локали, предоставляемой IntlProvider. Один и тот же компонент может выводить разные результаты:

  • 1,000.5 (en-US)
  • 1 000,5 (ru-RU)
  • 1.000,5 (de-DE)

Это влияет на:

  • разделители тысяч
  • десятичные символы
  • порядок символов валют
  • правила округления

Взаимодействие FormattedMessage и FormattedNumber

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

<FormattedMessage
  id="cart.total"
  defaultMessage="Итого: {price, number, currency}"
  values={{ price: 2599.99 }}
/>

В таком случае FormattedMessage делегирует форматирование чисел встроенному механизму number format.

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

При изменении locale в IntlProvider происходит полное переопределение форматирования:

  • пересборка строк сообщений
  • обновление правил pluralization
  • перерасчёт числовых форматов
  • перерендер компонентов FormattedMessage и FormattedNumber

Это обеспечивает консистентность интерфейса без ручного пересчёта значений.

Производственные особенности

При использовании в крупных приложениях важно учитывать:

  • кэширование форматтеров Intl для снижения нагрузки
  • стабильность id сообщений для предотвращения лишних перерендеров
  • разделение статических и динамических сообщений
  • избегание генерации ICU-строк во время рендера

FormattedMessage и FormattedNumber опираются на стандарт Intl API, что обеспечивает нативную производительность браузера и предсказуемость поведения в разных средах исполнения.