Imperative API
Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →
React Intl basiert auf mehreren API-Schichten und stellt diese bereit. Bei der Nutzung interagieren Sie sowohl mit der hier dokumentierten API als auch mit React-Komponenten.
Warum imperative API?
Während unsere Komponenten nahtlose React-Integration bieten, wird die imperative API in mehreren Szenarien empfohlen (manchmal benötigt):
-
Setzen von Textattributen wie
title,aria-labeletc., wo React-Komponenten nicht verwendbar sind (z.B.<img title/>) -
Formatierung von Text/Datumsangaben in non-React-Umgebungen wie Node, Server-APIs, Redux-Store, Tests...
-
Hochperformante Szenarien, wo die Anzahl gerenderter React-Komponenten zum Engpass wird (z.B. Finanz-Portfoliodarstellung, virtuelle Tabellen mit vielen Zellen...)
Das intl-Objekt
Das Herzstück von react-intl ist das intl-Objekt (vom Typ IntlShape). Es speichert einen Cache aller Intl.*-APIs, Konfigurationen, kompilierten Nachrichten etc. Der Lebenszyklus des intl-Objekts ist typischerweise an das locale und die enthaltenen messages gebunden. Bei locale-Wechsel sollte es neu erstellt werden.
Das intl-Objekt sollte aus Performance-Gründen möglichst wiederverwendet werden.
Es gibt mehrere Wege, auf das intl-Objekt zuzugreifen:
-
useIntl-Hook: Nach Deklaration IhresIntlProvidererhalten Sie Zugriff auf dasintl-Objekt via Aufruf in funktionalen React-Komponenten -
injectIntl-HOC: Inclass-basierten Komponenten wrappen Sie diese mit deminjectIntl-HOC;intlwird dann alspropverfügbar -
createIntl: In non-React-Umgebungen (Node, Vue, Angular, Tests etc.) erstellen Sie direkt einintl-Objekt mit derselben Konfiguration wie fürIntlProvider
useIntl-Hook
Für funktionale Komponenten ist der useIntl-Hook praktisch. Dieser useIntl-Hook erwartet keine Optionen als Argument. Typische Nutzung:
import React from 'react'
import {useIntl, FormattedDate} from 'react-intl'
const FunctionComponent: React.FC<{date: number | Date}> = ({date}) => {
const intl = useIntl()
return (
<span title={intl.formatDate(date)}>
<FormattedDate value={date} />
</span>
)
}
export default FunctionComponent
Um die API-Oberfläche sauber und einfach zu halten, bieten wir nur den useIntl-Hook im Paket an. Bei Bedarf können Benutzer diesen integrierten Hook wrappen, um benutzerdefinierte Hooks wie useFormatMessage einfach zu erstellen. Weitere allgemeine Informationen finden Sie in der offiziellen Einführung in React-Hooks auf der React-Website.
injectIntl-HOC
type WrappedComponentProps<IntlPropName extends string = 'intl'> = {
[k in IntlPropName]: IntlShape
}
type WithIntlProps<P> = Omit<P, keyof WrappedComponentProps> & {
forwardedRef?: React.Ref<any>
}
function injectIntl<
IntlPropName extends string = 'intl',
P extends WrappedComponentProps<IntlPropName> = WrappedComponentProps<any>,
>(
WrappedComponent: React.ComponentType<P>,
options?: Opts<IntlPropName>
): React.ComponentType<WithIntlProps<P>> & {
WrappedComponent: typeof WrappedComponent
}
Diese vom react-intl-Paket exportierte Factory erzeugt Higher-Order Components (HOCs). Sie wrappt React-Komponenten und injiziert die imperative Formatierungs-API via props (ähnlich dem connect-to-stores-Pattern in Flux-Implementierungen).
Standardmäßig wird die API via props.intl bereitgestellt, aber durch options.intlPropName konfigurierbar. Der Prop-Wert entspricht dem Typ IntlShape.
import React from 'react'
import {injectIntl, FormattedDate} from 'react-intl'
interface Props {
date: Date | number
}
const FunctionalComponent: React.FC<Props> = props => {
const {
date,
intl, // Injected by `injectIntl`
} = props
return (
<span title={intl.formatDate(date)}>
<FormattedDate value={date} />
</span>
)
}
export default injectIntl(FunctionalComponent)
createIntl
Dies ermöglicht die Erstellung eines IntlShape-Objekts ohne Verwendung von Provider. Dies ermöglicht die Formatierung von Elementen außerhalb des React-Lebenszyklus unter Wiederverwendung desselben intl-Objekts. Beispiel:
import {createIntl, createIntlCache, RawIntlProvider} from 'react-intl'
// This is optional but highly recommended
// since it prevents memory leak
const cache = createIntlCache()
const intl = createIntl({
locale: 'fr-FR',
messages: {}
}, cache)
// Call imperatively
intl.formatNumber(20)
// Pass it to IntlProvider
<RawIntlProvider value={intl}>{foo}</RawIntlProvider>
createIntlCache
Erstellt eine Cache-Instanz für die globale Nutzung über alle Locales hinweg. Dies memoisiert zuvor erstellte Intl.*-Konstruktoren für bessere Performance und ist lediglich ein In-Memory-Cache.
IntlShape
interface IntlConfig {
locale: string
timeZone?: string
formats: CustomFormats
textComponent?: React.ComponentType | keyof React.JSX.IntrinsicElements
messages: Record<string, string> | Record<string, MessageFormatElement[]>
defaultLocale: string
defaultFormats: CustomFormats
onError(err: string): void
onWarn(warning: string): void
}
interface IntlFormatters {
formatDate(value: number | Date | string, opts?: FormatDateOptions): string
formatTime(value: number | Date | string, opts?: FormatDateOptions): string
formatDateToParts(
value: number | Date | string,
opts?: FormatDateOptions
): Intl.DateTimeFormatPart[]
formatTimeToParts(
value: number | Date | string,
opts?: FormatDateOptions
): Intl.DateTimeFormatPart[]
formatRelativeTime(
value: number,
unit?: FormattableUnit,
opts?: FormatRelativeTimeOptions
): string
formatNumber(value: number, opts?: FormatNumberOptions): string
formatNumberToParts(
value: number,
opts?: FormatNumberOptions
): Intl.NumberFormatPart[]
formatPlural(
value: number | string,
opts?: FormatPluralOptions
): ReturnType<Intl.PluralRules['select']>
formatMessage(
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>
): string
formatMessage(
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T, R>>
): R
formatList(values: Iterable<string>, opts?: FormatListOptions): string
formatList(
values: Iterable<string | T>,
opts?: FormatListOptions
): T | string | Array<string | T>
formatListToParts(
values: Iterable<string | T>,
opts?: FormatListOptions
): Part[]
formatDisplayName(
value: string,
opts?: FormatDisplayNameOptions
): string | undefined
}
type IntlShape = IntlConfig & IntlFormatters
Dieses Interface wird vom react-intl-Paket exportiert und mit dem injectIntl-HOC kombiniert.
Das via injectIntl injizierte props.intl-Objekt besteht aus zwei Teilen:
-
IntlConfig: Die Intl-Metadaten, die als Props an das übergeordnete<IntlProvider>-Element übergeben werden. -
IntlFormatters: Die imperative Formatierungs-API, wie unten beschrieben.
locale, formats und messages
Das aktuelle Locale des Benutzers und in welchem die App gerendert werden soll. defaultLocale und defaultFormats dienen als Fallback oder während der Entwicklung und repräsentieren die Standardeinstellungen der App. Beachten Sie, dass es kein defaultMessages gibt, da jeder Nachrichtendeskriptor ein defaultMessage bereitstellt.
defaultLocale und defaultFormats
Standard-Locale und -Formate für den Fall, dass eine Nachricht nicht übersetzt ist (fehlt in messages). defaultLocale sollte das Locale sein, in dem die defaultMessages deklariert sind, um Satzkohärenz in einem Locale zu gewährleisten. Ohne defaultLocale oder bei falscher Konfiguration kann es vorkommen, dass ein Satz auf Englisch ist, aber eingebettete Datums-/Zeitangaben auf Spanisch erscheinen.
textComponent
Ermöglicht die Konfiguration des Standard-Wrappers für die <Formatted*>-Komponenten von React Intl. Wenn nicht angegeben, wird <React.Fragment> verwendet. Vor Version 3 kam span zum Einsatz; weitere Details finden Sie im Migrationsleitfaden.
onError
Ermöglicht die Bereitstellung eines benutzerdefinierten Fehlerhandlers. Standardmäßig werden Fehlermeldungen via console.error protokolliert, sofern NODE_ENV nicht auf production gesetzt ist.
wrapRichTextChunksInFragment
Bei der Formatierung von Rich-Text-Nachrichten erzeugt die Ausgabe den Typ Array<string | React.ReactElement>, was einen Key-Fehler auslösen kann. Dies umschließt die Ausgabe in einem einzelnen React.Fragment, um dies zu unterdrücken.
defaultRichTextElements
Eine Zuordnung von Tags zu Rich-Text-Formatierungsfunktionen. Dient der zentralisierten Formatierung gängiger Tags wie <b>, <p> oder der Durchsetzung von Design-Systemen im Codebase (z.B. standardisierte <a> oder <button>). Siehe https://github.com/formatjs/formatjs/issues/1752 für weitere Details.
formatDate
function formatDate(
value: number | Date | string,
options?: Intl.DateTimeFormatOptions & {format?: string}
): string
Diese Funktion gibt eine formatierte Datumszeichenkette zurück. Erwartet einen als Datum parsbaren value (d.h. isFinite(new Date(value)) ist wahr) und akzeptiert options, die DateTimeFormatOptions entsprechen.
intl.formatDate(Date.now(), { year: 'numeric', month: 'numeric', day: 'numeric', })
formatTime
function formatTime(
value: number | Date | string,
options?: Intl.DateTimeFormatOptions & {format?: string}
): string
Diese Funktion gibt ebenfalls eine formatierte Datumszeichenkette zurück, unterscheidet sich jedoch von formatDate durch folgende Standardoptionen:
{
hour: 'numeric',
minute: 'numeric',
}
Erwartet einen als Datum parsbaren value (d.h. isFinite(new Date(value)) ist wahr) und akzeptiert options, die DateTimeFormatOptions entsprechen.
intl.formatTime(Date.now()) /* "4:03 PM" */
formatDateTimeRange
Erfordert Intl.DateTimeFormat.prototype.formatRange, das nur eingeschränkt unterstützt wird. Verwenden Sie unser Polyfill für entsprechende Browser.
function formatDateTimeRange(
from: number | Date | string,
to: number | Date | string,
options?: Intl.DateTimeFormatOptions & {format?: string}
): string
Gibt eine formatierte Datums-/Zeitbereichszeichenkette zurück. Sowohl from als auch to müssen als Datum parsbar sein (d.h. isFinite(new Date(value)) muss wahr sein).
Erwartet 2 Werte (ein from-Datum und ein to-Datum) und akzeptiert options, die DateTimeFormatOptions entsprechen.
intl.formatDateTimeRange(new Date('2020-1-1'), new Date('2020-1-15'))
formatRelativeTime
Dies erfordert Intl.RelativeTimeFormat mit begrenzter Browserunterstützung. Verwenden Sie unser Polyfill für Kompatibilität.
type Unit =
| 'second'
| 'minute'
| 'hour'
| 'day'
| 'week'
| 'month'
| 'quarter'
| 'year'
type RelativeTimeFormatOptions = {
numeric?: 'always' | 'auto'
style?: 'long' | 'short' | 'narrow'
}
function formatRelativeTime(
value: number,
unit: Unit,
options?: Intl.RelativeTimeFormatOptions & {
format?: string
}
): string
Gibt eine formatierte relative Zeitzeichenkette zurück (z.B. "vor 1 Stunde"). Erwartet einen numerischen value, eine unit und options, die Intl.RelativeTimeFormatOptions entsprechen.
intl.formatRelativeTime(0)
intl.formatRelativeTime(-24, 'hour', {style: 'narrow'})
formatNumber
Verwendet Optionen von Intl.NumberFormat.
function formatNumber(
value: number,
options?: Intl.NumberFormatOptions & {format?: string}
): string
Gibt eine formatierte Zahlenzeichenkette zurück. Erwartet einen als Zahl parsbaren value und akzeptiert options, die NumberFormatOptions entsprechen.
intl.formatNumber(1000, {style: 'currency', currency: 'USD'})
Zahlenformatierung mit unit
Dies ist Teil von ES2020 NumberFormat.
Wir stellen ein Polyfill hier bereit. Die Typen von react-intl erlauben die Übergabe
einer zulässigen Einheit:
intl.formatNumber(1000, { style: 'unit', unit: 'kilobyte', unitDisplay: 'narrow', })
intl.formatNumber(1000, { unit: 'fahrenheit', unitDisplay: 'long', style: 'unit', })
formatPlural
type PluralFormatOptions = {
type?: 'cardinal' | 'ordinal' = 'cardinal'
}
function formatPlural(
value: number,
options?: Intl.PluralFormatOptions
): 'zero' | 'one' | 'two' | 'few' | 'many' | 'other'
Gibt eine Pluralkategoriezeichenkette zurück: "zero", "one", "two", "few", "many" oder "other". Erwartet einen als Zahl parsbaren value und akzeptiert options, die PluralFormatOptions entsprechen.
Niedrige Abstraktionsebene – die Ausgabe kann in einer switch-Anweisung verwendet werden, um spezifische Anzeigetexte auszuwählen.
intl.formatPlural(1)
intl.formatPlural(3, {style: 'ordinal'})
intl.formatPlural(4, {style: 'ordinal'})
Nur für Apps mit einer Sprache geeignet. Für mehrsprachige Apps stattdessen formatMessage verwenden.
formatList
Dies erfordert Intl.ListFormat, das nur eingeschränkte Browserunterstützung bietet. Verwenden Sie unser Polyfill, falls Sie diese Browser unterstützen möchten.
type ListFormatOptions = {
type?: 'disjunction' | 'conjunction' | 'unit'
style?: 'long' | 'short' | 'narrow'
}
function formatList(
elements: (string | React.ReactNode)[],
options?: Intl.ListFormatOptions
): string | React.ReactNode[]
Diese Funktion ermöglicht die i18n-sichere Verkettung von Listen. Beispiel bei en-Locale:
intl.formatList(['Me', 'myself', 'I'], {type: 'conjunction'})
intl.formatList(['5 hours', '3 minutes'], {type: 'unit'})
formatDisplayName
Dies erfordert Intl.DisplayNames, das nur eingeschränkte Browserunterstützung bietet. Verwenden Sie unser Polyfill, falls Sie diese Browser unterstützen möchten.
type FormatDisplayNameOptions = {
style?: 'narrow' | 'short' | 'long'
type?: 'language' | 'region' | 'script' | 'currency'
fallback?: 'code' | 'none'
}
function formatDisplayName(
value: string | number | Record<string, unknown>,
options?: FormatDisplayNameOptions
): string | undefined
Anwendungsbeispiele:
intl.formatDisplayName('zh-Hans-SG', {type: 'language'})
// ISO-15924 four letters script code to localized display name intl.formatDisplayName('Deva', {type: 'script'})
// ISO-4217 currency code to localized display name intl.formatDisplayName('CNY', {type: 'currency'})
// ISO-3166 two letters region code to localized display name intl.formatDisplayName('UN', {type: 'region'})
formatMessage
Nachrichtensyntax
Die String-/Nachrichtenformatierung ist eine Kernfunktion von React Intl und basiert auf ICU Message Formatting mittels ICU Message Syntax. Diese Syntax ermöglicht die Definition, Übersetzung und Laufzeitformatierung einfacher bis komplexer Nachrichten.
Einfache Nachricht:
Hello, {name}
Komplexe Nachricht:
Hello, {name}, you have {itemCount, plural,
=0 {no items}
one {# item}
other {# items}
}.
Siehe: Nachrichtensyntax-Leitfaden.
Nachrichtendeskriptor
React Intl verwendet Nachrichtendeskriptoren zur Definition von Standardnachrichten, die an formatMessage übergeben werden. Sie enthalten alle notwendigen Daten für Übersetzungen mit folgenden Eigenschaften:
-
id: Eindeutige, stabile Kennung der Nachricht -
description: Kontextinformation für Übersetzer zur Verwendung in der UI -
defaultMessage: Standardnachricht (üblicherweise auf Englisch)
type MessageDescriptor = {
id: string
defaultMessage?: string
description?: string | object
}
Inline deklarierte Nachrichten können mit unserem CLI aus Quellcode extrahiert werden.
Fallbacks bei der Nachrichtenformatierung
Die Nachrichtenformatierungs-APIs gehen einen Schritt weiter, um Fallbacks für häufige Fehlersituationen bereitzustellen; mindestens sollte immer ein nicht-leerer String zurückgegeben werden. Hier ist der Fallback-Algorithmus für die Nachrichtenformatierung:
-
Formatierung der übersetzten Nachricht via
idaus<IntlProvider> -
Fallback:
defaultMessageformatieren. -
Fallback auf Originaltext der übersetzten Nachricht via
id -
Fallback auf Originaltext von
defaultMessage -
Fallback: Literale Nachricht
idausgeben.
"Originaltext" bezeichnet hier die unveränderte Vorlage ohne Substitutionen.
Verwendung
type MessageFormatPrimitiveValue = string | number | boolean | null | undefined
function formatMessage(
descriptor: MessageDescriptor,
values?: Record<string, MessageFormatPrimitiveValue>
): string
function formatMessage(
descriptor: MessageDescriptor,
values?: Record<
string,
MessageFormatPrimitiveValue | React.ReactElement | FormatXMLElementFn
>
): string | React.ReactNode[]
Diese Funktion formatiert Nachrichtenstrings. Erwartet wird ein MessageDescriptor mit mindestens id und ein values-Objekt zur Platzhalterfüllung.
Wenn eine übersetzte Nachricht mit der id via messages-Prop an den <IntlProvider> übergeben wurde, wird diese formatiert, andernfalls wird auf die Formatierung von defaultMessage zurückgegriffen. Details siehe Formatierungsfallbacks.
function () { const messages = defineMessages({ greeting: { id: 'app.greeting', defaultMessage: 'Hello, {name}!', description: 'Greeting to welcome the user to the app', }, }) return intl.formatMessage(messages.greeting, {name: 'Eric'}) }
mit ReactElement
function () { const messages = defineMessages({ greeting: { id: 'app.greeting', defaultMessage: 'Hello, {name}!', description: 'Greeting to welcome the user to the app', }, }) return intl.formatMessage(messages.greeting, {name: <b>Eric</b>}) }
mit Rich-Text-Formatierung
function () { const messages = defineMessages({ greeting: { id: 'app.greeting', defaultMessage: 'Hello, <bold>{name}</bold>!', description: 'Greeting to welcome the user to the app', }, }) return intl.formatMessage(messages.greeting, { name: 'Eric', bold: str => <b>{str}</b>, }) }
Die Nachricht wurde mittels defineMessages für Extraktion via babel-plugin-formatjs definiert, ist aber ohne Babel-Plugin optional.
Nachrichten ohne Platzhalter sind zulässig und stellen den häufigsten Typ dar.
defineMessages/defineMessage
interface MessageDescriptor {
id?: string
description?: string | object
defaultMessage?: string
}
function defineMessages(
messageDescriptors: Record<string, MessageDescriptor>
): Record<string, MessageDescriptor>
function defineMessage(messageDescriptor: MessageDescriptor): MessageDescriptor
Diese Funktionen werden vom react-intl-Paket exportiert und dienen als Hook für unser CLI und Babel/TS-Plugin zur Kompilierung von Standardnachrichten in JavaScript-Dateien. Diese Funktion gibt das übergebene Nachrichtendeskriptor-Map-Objekt unverändert zurück.
import {defineMessages, defineMessage} from 'react-intl'
const messages = defineMessages({
greeting: {
id: 'app.home.greeting',
description: 'Message to greet the user.',
defaultMessage: 'Hello, {name}!',
},
})
const msg = defineMessage({
id: 'single',
defaultMessage: 'single message',
description: 'header',
})