Как отображать информацию о валюте в 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">
Select currency: <CurrencyInfo code="EUR" display="name" />
</label>
<table>
<thead>
<tr>
<th>
Amount (<CurrencyInfo code="USD" display="symbol" />)
</th>
</tr>
</thead>
</table>
<p>
Transaction currency: <CurrencyInfo code="GBP" display="code" />
</p>
</div>
);
}
В каждом контексте используется формат, который лучше всего подходит для задачи: полные названия — для интерфейсов выбора, символы — для компактных отображений, коды — для точных технических ссылок. Компонент автоматически локализует данные на основе локали пользователя из IntlProvider.