Währungsbeträge in TanStack Start v1 formatieren
Preise mit Währungssymbolen und Trennzeichen anzeigen
Problem
Preise vereinen zwei Lokalisierungsherausforderungen: Währungsdarstellung und Zahlenformatierung. Derselbe Geldbetrag erscheint in den Vereinigten Staaten als $1,200.50 und in Deutschland als 1 200,50 €. Das Währungssymbol wandert, Dezimal- und Tausendertrennzeichen tauschen ihre Positionen, 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 der Währung und dem Gebietsschema des Benutzers. Dies kombiniert die Platzierung des Währungssymbols mit gebietsschemaspezifischen Zahlenformatierungsregeln und erzeugt Preise, die den regionalen Erwartungen entsprechen, wie Geld aussehen sollte.
Verwenden Sie die Methode formatNumber von react-intl mit der Option style: 'currency', um sowohl den Währungscode als auch die Formatierungskonventionen des Benutzergebietsschemas anzuwenden. Die Intl.NumberFormat-API des Browsers übernimmt automatisch die Symbolplatzierung, Trennzeichenwahl und Abstände.
Schritte
1. Erstellen Sie eine Währungsformatierungskomponente
Erstellen Sie eine wiederverwendbare Komponente, die einen numerischen Wert und einen Währungscode akzeptiert und dann den Preis unter Verwendung des Benutzergebietsschemas 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 Hook useIntl bietet Zugriff auf die Formatierungs-API. Die Methode formatNumber mit style: 'currency' wendet sowohl das Währungssymbol als auch die gebietsschemaspezifische Zahlenformatierung an.
2. Verwenden Sie die Komponente mit verschiedenen Währungen
Zeigen Sie Preise in Ihrer gesamten 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. Preise mit benutzerdefinierter Dezimalpräzision formatieren
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 Dezimaldarstellung für alle Preise, auch wenn der Wert eine ganze Zahl wie 100 ist.
4. Eine Hilfsfunktion für Inline-Formatierung erstellen
Für Fälle, in denen ein Komponenten-Wrapper nicht erforderlich ist, erstellen Sie eine Formatierungs-Hilfsfunktion.
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>
);
}
Die Hilfsfunktion gibt eine einfache Zeichenkette zurück, die für jeden Kontext geeignet ist, in dem JSX-Komponenten nicht verwendet werden können.