Как форматировать числа для разных локалей в TanStack Start v1
Отображение чисел с разделителями, специфичными для локали
Проблема
Числа записываются по-разному в разных странах. То, что в Соединенных Штатах выглядит как 10,000.5, в Германии становится 10.000,5 — запятые и точки полностью меняются местами. Это не вопрос предпочтений или стиля, а вопрос читаемости. Немецкий пользователь, видя 10,000.5, может прочитать это как десять, игнорируя разделители групп. Американский пользователь, видя 10.000,5, может прочитать это как десять тысяч, игнорируя десятичный разделитель. Одни и те же цифры, противоположные значения.
Когда приложения отображают числа без учета региональных форматов, это создает путаницу и подрывает доверие. Пользователи ожидают, что числа будут следовать привычным им шаблонам, и отклонения от этих шаблонов заставляют их останавливаться, переосмысливать и сомневаться в правильности данных.
Решение
Форматируйте числа в соответствии с локалью пользователя, используя региональные правила для десятичных и групповых разделителей. Это преобразует числовые значения в строки, которые соответствуют правилам форматирования, знакомым пользователям в их регионе.
React-intl предоставляет компоненты и хуки, которые используют встроенный API Intl.NumberFormat браузера для применения форматирования, специфичного для локали. Передавая числовое значение и текущую локаль, эти инструменты автоматически выбирают правильные разделители, группировку цифр и другие региональные особенности. Результатом является отформатированная строка, которая соответствует ожиданиям пользователя без ручной обработки строк или логики, зависящей от локали, в ваших компонентах.
Шаги
1. Создайте компонент отображения чисел с использованием FormattedNumber
Создайте компонент, который принимает числовое значение и отображает его с форматированием, соответствующим локали, используя компонент FormattedNumber из react-intl.
import { FormattedNumber } from "react-intl";
interface PriceDisplayProps {
value: number;
}
export function PriceDisplay({ value }: PriceDisplayProps) {
return (
<div>
<FormattedNumber value={value} />
</div>
);
}
Компонент FormattedNumber автоматически применяет десятичные и групповые разделители, характерные для локали. Он считывает локаль из ближайшего IntlProvider в дереве компонентов и форматирует число соответствующим образом.
2. Форматирование чисел с использованием определённых стилей
Настройте форматирование чисел, передавая параметры стиля в FormattedNumber для валют, процентов или единиц измерения.
import { FormattedNumber } from "react-intl";
interface MetricsProps {
revenue: number;
growthRate: number;
fileSize: number;
}
export function Metrics({ revenue, growthRate, fileSize }: MetricsProps) {
return (
<div>
<p>
Доход:{" "}
<FormattedNumber value={revenue} style="currency" currency="USD" />
</p>
<p>
Рост: <FormattedNumber value={growthRate} style="percent" />
</p>
<p>
Размер:{" "}
<FormattedNumber
value={fileSize}
style="unit"
unit="megabyte"
unitDisplay="short"
/>
</p>
</div>
);
}
Свойство style управляет режимом форматирования. Для форматирования валют требуется код currency, форматирование процентов автоматически умножает значение на 100, а для форматирования единиц измерения требуется идентификатор unit. Все стили учитывают правила активной локали.
3. Императивное форматирование чисел с использованием useIntl
Используйте хук useIntl для форматирования чисел в контекстах, где компоненты не подходят, например, для генерации динамических атрибутов или подготовки данных для API, не связанных с React.
import { useIntl } from "react-intl";
interface ChartTooltipProps {
dataPoint: number;
}
export function ChartTooltip({ dataPoint }: ChartTooltipProps) {
const intl = useIntl();
const formattedValue = intl.formatNumber(dataPoint, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
return <div title={formattedValue}>{formattedValue}</div>;
}
Метод formatNumber возвращает отформатированную строку сразу, что делает его подходящим для атрибутов, aria-меток или любого контекста, где требуется отформатированное значение в виде строки, а не React-элемента.
4. Применение пользовательских параметров форматирования
Управляйте точностью, группировкой и нотацией, передавая Intl.NumberFormatOptions в FormattedNumber или formatNumber.
import { FormattedNumber } from "react-intl";
interface StatisticProps {
value: number;
compact?: boolean;
}
export function Statistic({ value, compact }: StatisticProps) {
return (
<div>
<FormattedNumber
value={value}
notation={compact ? "compact" : "standard"}
minimumFractionDigits={0}
maximumFractionDigits={2}
/>
</div>
);
}
Такие параметры, как notation, minimumFractionDigits и maximumFractionDigits, управляют отображением числа. Компактная нотация преобразует большие числа в сокращённые формы, такие как "1.2M", с учётом локальных сокращений.