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">
        通貨を選択: <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からユーザーのロケールに基づいて自動的にローカライゼーションを処理します。