Как отображать информацию о валюте в React Router v7
Отображение кодов, названий и символов валют
Проблема
Приложения часто нуждаются в отображении информации о валюте без форматированной цены. Например, селектор валют может показывать "USD" или "доллар США", а финансовая панель — только символ "$". Каждый формат служит своей цели, но все они сталкиваются с общими проблемами. Код ISO "USD" точен, но непонятен для нетехнических пользователей. Полное название "доллар США" ясно, но требует перевода для международной аудитории. Символ "$" компактен, но неоднозначен — он может обозначать доллары США, Канады или Австралии в зависимости от контекста. Неправильный выбор формата сбивает пользователей с толку и подрывает доверие к финансовым интерфейсам.
Эта проблема усугубляется при создании многоязычных приложений. Название валюты, подходящее для английского языка, может не переводиться напрямую на другие языки, а использование символов варьируется в зависимости от локали. Жёсткое кодирование этих значений создаёт нагрузку на обслуживание и ограничивает охват вашего приложения.
Решение
Используйте метод formatDisplayName из react-intl для отображения локализованных названий и кодов валют, а также API Intl.NumberFormat браузера для извлечения символов валют. Метод formatDisplayName принимает код валюты и возвращает соответствующее локализованное название на основе локали пользователя, автоматически обрабатывая перевод. Для символов отформатируйте пример числа с валютой и извлеките символ из результата.
Создайте вспомогательные функции или компоненты для каждого формата отображения — полного названия, символа или кода — чтобы выбрать подходящее представление для каждого контекста. Такой подход централизует логику отображения валют и обеспечивает согласованность в вашем приложении, уважая предпочтения локали пользователя.
Шаги
1. Создайте вспомогательную функцию для отображения локализованных названий валют
Используйте метод formatDisplayName с type: 'currency', чтобы преобразовать коды валют ISO в локализованные полные названия.
import { useIntl } from "react-intl";
export function CurrencyName({ code }: { code: string }) {
const intl = useIntl();
const name = intl.formatDisplayName(code, { type: "currency" });
return <span>{name}</span>;
}
Когда локаль установлена на "en", а код равен "CNY", это отображает "Chinese Yuan". Метод автоматически переводит название на основе текущей локали из IntlProvider.
2. Создайте вспомогательную функцию для извлечения и отображения символов валют
Используйте Intl.NumberFormat с formatToParts, чтобы извлечь символ валюты, фильтруя части с type === "currency".
function getCurrencySymbol(locale: string, currency: string): string {
const parts = new Intl.NumberFormat(locale, {
style: "currency",
currency,
currencyDisplay: "narrowSymbol",
}).formatToParts(0);
const currencyPart = parts.find((part) => part.type === "currency");
return currencyPart?.value || currency;
}
export function CurrencySymbol({ code }: { code: string }) {
const intl = useIntl();
const symbol = getCurrencySymbol(intl.locale, code);
return <span>{symbol}</span>;
}
Опция currencyDisplay управляет формой отображения валюты, где "narrowSymbol" предоставляет наиболее компактное представление. Этот подход автоматически обрабатывает размещение и форматирование символов, специфичных для локали.
3. Создайте компонент, предлагающий несколько вариантов отображения
Создайте гибкий компонент, который принимает пропс режима отображения для переключения между форматами кода, символа и названия.
import { useIntl } from "react-intl";
type CurrencyDisplayMode = "code" | "symbol" | "name";
interface CurrencyInfoProps {
code: string;
display?: CurrencyDisplayMode;
}
export function CurrencyInfo({ code, display = "symbol" }: CurrencyInfoProps) {
const intl = useIntl();
if (display === "name") {
const name = intl.formatDisplayName(code, { type: "currency" });
return <span>{name}</span>;
}
if (display === "symbol") {
const parts = new Intl.NumberFormat(intl.locale, {
style: "currency",
currency: code,
currencyDisplay: "narrowSymbol",
}).formatToParts(0);
const symbol =
parts.find((part) => part.type === "currency")?.value || code;
return <span>{symbol}</span>;
}
return <span>{code}</span>;
}
Этот компонент централизует логику отображения валют и упрощает переключение форматов в зависимости от контекста пользовательского интерфейса. Используйте display="name" для селекторов валют, где важна ясность, display="symbol" для компактного отображения, например, в заголовках таблиц, и display="code" для технических или финансовых отчетов.
4. Используйте компонент в разных контекстах
Применяйте соответствующий режим отображения в зависимости от того, где информация о валюте появляется в вашем интерфейсе.
export default function CurrencyExample() {
return (
<div>
<label htmlFor="currency-select">
Выберите валюту: <CurrencyInfo code="EUR" display="name" />
</label>
<table>
<thead>
<tr>
<th>
Сумма (<CurrencyInfo code="USD" display="symbol" />)
</th>
</tr>
</thead>
</table>
<p>
Валюта транзакции: <CurrencyInfo code="GBP" display="code" />
</p>
</div>
);
}
Каждый контекст использует формат, который лучше всего соответствует его цели: полные названия для интерфейсов выбора, символы для компактного отображения и коды для точных технических ссылок. Компонент автоматически обрабатывает локализацию на основе локали пользователя из IntlProvider.