Wie man Währungsbeträge in TanStack Start v1 formatiert

Preise mit Währungssymbolen und Trennzeichen anzeigen

Problem

Preise kombinieren zwei Lokalisierungsherausforderungen: Währungsdarstellung und Zahlenformatierung. Der gleiche Geldbetrag erscheint als $1,200.50 in den Vereinigten Staaten und als 1 200,50 € in Deutschland. Das Währungssymbol verschiebt sich, die Dezimal- und Gruppierungstrennzeichen werden vertauscht, und sogar die Abstände ändern sich.

Diese Konventionen sind keine Präferenzen, sondern Erwartungen. Die Anzeige von Preisen in einem ungewohnten Format lässt Benutzer daran zweifeln, ob sie den korrekten Betrag sehen. Ein Preis, der einem deutschen Benutzer als "1200.50 EUR" oder einem US-Benutzer als "1.200,50$" angezeigt wird, erzeugt Reibung und untergräbt das Vertrauen.

Lösung

Formatieren Sie Geldbeträge basierend auf sowohl der Währung als auch dem Gebietsschema des Benutzers. Dies kombiniert die Platzierung des Währungssymbols mit den gebietsspezifischen Regeln zur Zahlenformatierung und erzeugt Preise, die den regionalen Erwartungen entsprechen, wie Geld aussehen sollte.

Verwenden Sie die formatNumber-Methode von react-intl mit der Option style: 'currency', um sowohl den Währungscode als auch die Formatierungskonventionen des Gebietsschemas des Benutzers anzuwenden. Die Intl.NumberFormat-API des Browsers übernimmt automatisch die Symbolplatzierung, die Auswahl der Trennzeichen und die Abstände.

Schritte

1. Erstellen einer Währungsformatierungskomponente

Erstellen Sie eine wiederverwendbare Komponente, die einen numerischen Wert und einen Währungscode akzeptiert und dann den Preis unter Verwendung des Gebietsschemas des Benutzers formatiert.

import { useIntl } from "react-intl";

interface PriceProps {
  value: number;
  currency: string;
}

export function Price({ value, currency }: PriceProps) {
  const intl = useIntl();

  const formattedPrice = intl.formatNumber(value, {
    style: "currency",
    currency: currency,
  });

  return <span>{formattedPrice}</span>;
}

Der useIntl-Hook bietet Zugriff auf die Formatierungs-API. Die formatNumber-Methode mit style: 'currency' wendet sowohl das Währungssymbol als auch die gebietsspezifische Zahlenformatierung an.

2. Verwenden der Komponente mit verschiedenen Währungen

Zeigen Sie Preise in Ihrer Anwendung an, indem Sie den numerischen Betrag und den Währungscode übergeben.

export default function ProductCard() {
  return (
    <div>
      <h2>Premium Plan</h2>
      <Price value={1200.5} currency="USD" />
    </div>
  );
}

Die Komponente formatiert den Preis automatisch entsprechend der Locale des Benutzers. Ein US-Benutzer sieht "$1,200.50", während ein deutscher Benutzer "1.200,50 $" sieht.

3. Formatieren von Preisen mit benutzerdefinierter Dezimalpräzision

Steuern Sie die Anzahl der angezeigten Dezimalstellen, indem Sie die Optionen minimumFractionDigits und maximumFractionDigits hinzufügen.

export function PriceWithPrecision({ value, currency }: PriceProps) {
  const intl = useIntl();

  const formattedPrice = intl.formatNumber(value, {
    style: "currency",
    currency: currency,
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  });

  return <span>{formattedPrice}</span>;
}

Dies gewährleistet eine konsistente Dezimalanzeige bei allen Preisen, selbst wenn der Wert eine ganze Zahl wie 100 ist.

4. Erstellen eines Helfers für Inline-Formatierung

Für Fälle, in denen ein Komponenten-Wrapper unnötig ist, erstellen Sie eine Formatierungshilfsfunktion.

import { useIntl } from "react-intl";

export function useFormatCurrency() {
  const intl = useIntl();

  return (value: number, currency: string) => {
    return intl.formatNumber(value, {
      style: "currency",
      currency: currency,
    });
  };
}

Verwenden Sie diesen Hook, wenn Sie formatierte Preise in Attributen, berechneten Werten oder anderen Nicht-JSX-Kontexten benötigen.

export function CheckoutSummary({ total }: { total: number }) {
  const formatCurrency = useFormatCurrency();

  return (
    <button aria-label={`Pay ${formatCurrency(total, "USD")}`}>Checkout</button>
  );
}

Der Helper gibt einen einfachen String zurück, der für jeden Kontext geeignet ist, in dem JSX-Komponenten nicht verwendet werden können.