FormatJS представляет собой экосистему для интернационализации JavaScript-приложений, основанную на ICU MessageFormat. В React-части библиотеки ключевую роль играют компоненты отображения локализованных сообщений и значений, среди которых особое значение имеют FormattedMessage и FormattedNumber.
FormattedMessage является декларативным компонентом для вывода локализованных строк, поддерживающих интерполяцию, склонения, множественные формы и вложенные структуры. Он интегрируется с системой сообщений ICU и использует контекст intl, предоставляемый провайдером интернационализации.
Сообщения задаются в формате ICU:
{
"greeting": "Привет, {name}!"
}
Использование компонента:
<FormattedMessage id="greeting" values={{ name: "Алексей" }} />
Механизм работы заключается в поиске строки по id, последующем разборе шаблона и подстановке значений через values.
Уникальный идентификатор сообщения в словаре локализации. Используется для извлечения строки из набора переводов.
Fallback-строка, применяемая при отсутствии перевода для текущей локали.
<FormattedMessage
id="welcome.text"
defaultMessage="Welcome, {name}"
values={{ name: "User" }}
/>
Объект подстановок, содержащий переменные, используемые внутри 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 }} />
Система автоматически применяет правила выбранного языка, включая языки со сложной морфологией.
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 отвечает за локализованное представление числовых значений с использованием 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. Один и тот же компонент может выводить разные результаты:
Это влияет на:
Оба компонента часто используются совместно для построения локализованных интерфейсов, где числовые значения встроены в текстовые шаблоны ICU.
<FormattedMessage
id="cart.total"
defaultMessage="Итого: {price, number, currency}"
values={{ price: 2599.99 }}
/>
В таком случае FormattedMessage делегирует форматирование чисел встроенному механизму number format.
При изменении locale в IntlProvider происходит полное переопределение форматирования:
Это обеспечивает консистентность интерфейса без ручного пересчёта значений.
При использовании в крупных приложениях важно учитывать:
FormattedMessage и FormattedNumber опираются на стандарт Intl API, что обеспечивает нативную производительность браузера и предсказуемость поведения в разных средах исполнения.