Wie man Zahlen für verschiedene Spracheinstellungen in Next.js (Pages Router) v16 formatiert

Zahlen mit sprachspezifischen Trennzeichen anzeigen

Problem

Zahlen werden weltweit unterschiedlich geschrieben. Was in den Vereinigten Staaten als 10,000.5 erscheint, wird in Deutschland zu 10.000,5 - Kommas und Punkte tauschen ihre Rollen vollständig. Dies ist keine Frage der Präferenz oder des Stils, sondern der Lesbarkeit. Ein deutscher Benutzer, der 10,000.5 sieht, könnte es als zehn lesen und die Gruppierungstrennzeichen ignorieren. Ein amerikanischer Benutzer, der 10.000,5 sieht, könnte es als zehntausend lesen und das Dezimaltrennzeichen ignorieren. Die gleichen Ziffern, entgegengesetzte Bedeutungen.

Wenn Anwendungen Zahlen ohne lokalisierungsbewusstes Formatting anzeigen, riskieren sie, Benutzer zu verwirren oder falsche Informationen zu vermitteln. Währungsbeträge, Prozentsätze, Messungen und Statistiken hängen alle von regionalen Konventionen ab, die Benutzer seit ihrer Kindheit gelernt haben.

Lösung

Formatieren Sie Zahlen basierend auf der Locale des Benutzers und verwenden Sie regionale Regeln für Dezimal- und Gruppierungstrennzeichen. Dies verwandelt numerische Werte in Zeichenketten, die den Formatierungsregeln folgen, die Benutzern in ihrer Region vertraut sind.

react-intl bietet zwei Ansätze: die <FormattedNumber>-Komponente für deklarative Formatierung in JSX und die formatNumber-Methode aus dem useIntl-Hook für imperative Formatierung. Beide basieren auf der Intl.NumberFormat-API des Browsers und wenden automatisch die in Ihrem IntlProvider konfigurierte Locale an. Die formatierte Ausgabe respektiert regionale Konventionen für Tausendertrennzeichen, Dezimalpunkte und Zifferngruppierung.

Schritte

1. Erstellen Sie eine Komponente, die Zahlen deklarativ formatiert

Die <FormattedNumber>-Komponente verwendet die formatNumber- und Intl.NumberFormat-APIs und akzeptiert eine value-Prop zusammen mit Optionen, die Intl.NumberFormatOptions entsprechen.

import { FormattedNumber } from "react-intl";

export default function ProductPrice({ price }: { price: number }) {
  return (
    <div>
      <FormattedNumber value={price} />
    </div>
  );
}

Standardmäßig rendert <FormattedNumber> die formatierte Zahl in ein React.Fragment. Die Komponente liest die Locale vom nächsten IntlProvider und wendet die entsprechenden Formatierungsregeln an.

2. Zahlen mit spezifischen Optionen formatieren

Übergeben Sie Formatierungsoptionen, um zu steuern, wie Zahlen dargestellt werden. Häufige Optionen sind minimumFractionDigits, maximumFractionDigits und style.

import { FormattedNumber } from "react-intl";

export default function Statistics({ value }: { value: number }) {
  return (
    <dl>
      <dt>Gesamtnutzer</dt>
      <dd>
        <FormattedNumber
          value={value}
          minimumFractionDigits={0}
          maximumFractionDigits={0}
        />
      </dd>
      <dt>Konversionsrate</dt>
      <dd>
        <FormattedNumber
          value={value / 100}
          style="percent"
          minimumFractionDigits={2}
        />
      </dd>
    </dl>
  );
}

Diese Props entsprechen den Intl.NumberFormatOptions und geben Ihnen Kontrolle über Präzision und Darstellung, während gleichzeitig lokalspezifische Trennzeichen beibehalten werden.

3. Zahlen imperativ mit dem useIntl-Hook formatieren

Wenn eine Komponente als Funktionskomponente ausgedrückt werden kann, bietet der useIntl-Hook Zugriff auf das intl-Objekt, das eine formatNumber-Methode enthält.

import { useIntl } from "react-intl";

export default function DataTable({ rows }: { rows: number[] }) {
  const intl = useIntl();

  return (
    <table>
      <tbody>
        {rows.map((value, index) => (
          <tr key={index}>
            <td>{intl.formatNumber(value)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Die formatNumber-Funktion gibt einen formatierten Zahlenstring zurück und akzeptiert einen Wert, der als Zahl geparst werden kann, zusammen mit Optionen, die den NumberFormatOptions entsprechen.

4. Zahlen in Nicht-JSX-Kontexten formatieren

Verwenden Sie formatNumber, wenn Sie formatierte Zahlen in Attributen, Variablen oder anderen Kontexten benötigen, in denen Komponenten nicht verwendet werden können.

import { useIntl } from "react-intl";

export default function Chart({ dataPoints }: { dataPoints: number[] }) {
  const intl = useIntl();

  const formattedLabel = intl.formatNumber(dataPoints[0], {
    notation: "compact",
    maximumFractionDigits: 1,
  });

  return (
    <div>
      <img
        src="/chart.png"
        alt={`Diagramm zeigt ${formattedLabel} Elemente`}
        title={formattedLabel}
      />
    </div>
  );
}

Die imperative API ist essenziell für die Einstellung von Textattributen wie title, aria-label oder alt, bei denen React-Komponenten nicht gerendert werden können.