React Router v7で通貨情報を表示する方法

通貨コード、名称、記号を表示する

問題

アプリケーションでは、フォーマットされた価格を表示せずに通貨情報を表示する必要がよくあります。通貨セレクターには「USD」や「米ドル」が表示され、財務ダッシュボードには「$」記号のみが表示される場合があります。各フォーマットは異なる目的を果たしますが、すべてに共通の課題があります。ISOコード「USD」は正確ですが、技術者以外のユーザーには馴染みがありません。完全名称「米ドル」は明確ですが、国際的なユーザー向けには翻訳が必要です。記号「$」はコンパクトですが曖昧で、文脈によって米ドル、カナダドル、オーストラリアドルを表す可能性があります。誤ったフォーマットを選択すると、ユーザーを混乱させ、金融インターフェースへの信頼を損ないます。

多言語アプリケーションを構築する際、この課題はさらに複雑になります。英語で機能する通貨名が他の言語に直接翻訳できない場合があり、記号の表記規則はロケールによって異なります。これらの値をハードコーディングすると、メンテナンスの負担が増え、アプリケーションのリーチが制限されます。

解決策

react-intlのformatDisplayNameメソッドを使用してローカライズされた通貨名とコードを表示し、ブラウザのIntl.NumberFormat APIを活用して通貨記号を抽出します。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.NumberFormatformatToPartsを使用し、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>;
}

このコンポーネントは通貨表示ロジックを一元化し、UIコンテキストに基づいて形式を簡単に切り替えられるようにします。明確性が重要な通貨セレクターには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からのユーザーのロケールに基づいて、自動的にローカライゼーションを処理します。