Componenti
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
React Intl fornisce un set di componenti React che offrono un modo dichiarativo per configurare un contesto i18n e formattare date, numeri e stringhe per la visualizzazione in un'interfaccia web. I componenti renderizzano elementi React basandosi sull'API imperativa di React Intl.
Perché Componenti?
Oltre a offrire un approccio idiomatico per integrare l'internazionalizzazione in un'app React, i componenti <Formatted*> presentano vantaggi rispetto all'uso diretto dell'API imperativa:
-
Renderizzano elementi React che si compongono perfettamente con altri componenti
-
Supportano la formattazione di messaggi/stringhe rich text in
<FormattedMessage> -
Implementano funzionalità avanzate come l'aggiornamento dinamico di
<FormattedRelativeTime> -
Forniscono definizioni di tipo TypeScript
IntlProvider
React Intl utilizza il pattern del provider per delimitare un contesto i18n a un albero di componenti. Ciò consente di fornire configurazioni come la localizzazione corrente e i messaggi tradotti alla radice dell'albero, rendendoli disponibili ai componenti <Formatted*>. Questo concetto è analogo a quanto fanno framework Flux come Redux per fornire accesso a uno store.
Tutte le app che utilizzano React Intl devono impiegare <IntlProvider> o <RawIntlProvider>.
Questo componente configura il contesto i18n per un albero. Tipicamente avvolge il componente root dell'app così che l'intera applicazione rientri nel contesto i18n configurato. Di seguito le proprietà configurabili:
interface IntlConfig {
locale: string
formats: CustomFormats
messages: Record<string, string> | Record<string, MessageFormatElement[]>
defaultLocale: string
defaultFormats: CustomFormats
timeZone?: string
textComponent?: React.ComponentType | keyof React.JSX.IntrinsicElements
wrapRichTextChunksInFragment?: boolean
defaultRichTextElements?: Record<string, FormatXMLElementFn<React.ReactNode>>
onError(err: string): void
}
locale, formats e messages
La localizzazione corrente dell'utente e quella in cui dovrebbe essere renderizzata l'applicazione. defaultLocale e defaultFormats servono come fallback o durante lo sviluppo e rappresentano le impostazioni predefinite dell'app. Notare l'assenza di defaultMessages: ciò avviene perché ogni Message Descriptor fornisce un proprio defaultMessage.
defaultLocale e defaultFormats
Localizzazione e formati predefiniti da usare quando un messaggio non è tradotto (assente da messages). defaultLocale dovrebbe corrispondere alla localizzazione in cui sono dichiarati i defaultMessage per garantire coerenza testuale. Senza defaultLocale o se impostata in modo errato, potresti trovarti in scenari dove una frase è in inglese ma date/ore incorporate sono in spagnolo.
textComponent
Configura il wrapper predefinito per i componenti <Formatted*>. Se non specificato, viene usato <React.Fragment>. Prima della V3 si utilizzava span; consultare la migration guide per dettagli.
onError
Consente all'utente di fornire un gestore di errori personalizzato. Per impostazione predefinita, gli errori vengono registrati tramite console.error se NODE_ENV non è impostato su production.
onWarn
Consente di definire un gestore personalizzato per i warning. Per default, i warning vengono registrati con console.warning se NODE_ENV non è production.
wrapRichTextChunksInFragment
Nella formattazione di messaggi rich text, l'output è di tipo Array<string | React.ReactElement>, che causerebbe errori di chiave. Questa opzione avvolge l'output in un singolo React.Fragment per evitare il problema.
defaultRichTextElements
Una mappa che associa tag a funzioni di formattazione per rich text. Offre un modo centralizzato per formattare tag comuni come <b>, <p>... o per applicare sistemi di design specifici nel codice (es. <a> o <button> standardizzati). Vedi https://github.com/formatjs/formatjs/issues/1752 per maggiori dettagli.
Queste proprietà si combinano con quelle specifiche di <IntlProvider>:
Props:
props: IntlConfig &
{
children: ReactNode,
}
È obbligatorio fornire elementi figlio a <IntlProvider>.
Esempio:
const App = ({importantDate}) => (
<div>
<FormattedDate
value={importantDate}
year="numeric"
month="long"
day="numeric"
weekday="long"
/>
</div>
)
ReactDOM.render(
<IntlProvider locale={navigator.language}>
<App importantDate={new Date(1459913574887)} />
</IntlProvider>,
document.getElementById('container')
)
Supponendo che navigator.language sia "fr":
<div>mardi 5 avril 2016</div>
RawIntlProvider
Rappresenta l'oggetto sottostante React.Context.Provider utilizzato da IntlProvider. Può essere usato con createIntl:
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)
// Pass it to IntlProvider
<RawIntlProvider value={intl}>{foo}</RawIntlProvider>
FormattedDate
Questo componente utilizza le API formatDate e Intl.DateTimeFormat, e ha props che corrispondono a DateTimeFormatOptions.
Props:
props: Intl.DateTimeFormatOptions &
{
value: any,
format: string,
children: (formattedDate: string) => ReactElement,
}
Per default <FormattedDate> renderizza la data formattata in un <React.Fragment>. Per personalizzare il rendering:
- Avvolgere con un altro elemento React (scelta consigliata)
- Passare una funzione come figlio
Esempio:
<FormattedDate value={new Date(1459832991883)} />
Esempio con Opzioni:
<FormattedDate value={new Date(1459832991883)} year="numeric" month="long" day="2-digit" />
FormattedDateParts
Richiede Intl.DateTimeFormat.prototype.formatToParts non disponibile in IE11. Utilizza il nostro polyfill per supportare IE11.
Questo componente offre maggiore personalizzazione rispetto a FormattedDate, consentendo alla funzione children di accedere alle parti sottostanti della data formattata. L'elenco delle parti disponibili è qui.
Props:
props: Intl.DateTimeFormatOptions &
{
value: any,
format: string,
children: (parts: Intl.DateTimeFormatPart[]) => ReactElement,
}
<FormattedDateParts value={new Date(1459832991883)} year="numeric" month="long" day="2-digit" > {parts => ( <> <b>{parts[0].value}</b> {parts[1].value} <small>{parts[2].value}</small> </> )} </FormattedDateParts>
FormattedTime
Questo componente utilizza le API formatTime e Intl.DateTimeFormat e ha props che corrispondono alle DateTimeFormatOptions specificate sopra, con i seguenti valori predefiniti:
{
hour: 'numeric',
minute: 'numeric',
}
Props:
props: DateTimeFormatOptions &
{
value: any,
format: string,
children: (formattedDate: string) => ReactElement,
}
Per impostazione predefinita <FormattedTime> renderizza l'ora formattata in un React.Fragment. Per personalizzare il rendering, è possibile wrapparlo con un altro elemento React (scelta consigliata) o passare una funzione come children.
Esempio:
<FormattedTime value={new Date(1459832991883)} />
FormattedTimeParts
Richiede Intl.DateTimeFormat.prototype.formatToParts non disponibile in IE11. Utilizza il nostro polyfill per supportare IE11.
Questo componente offre maggiore personalizzazione rispetto a FormattedTime, consentendo alla funzione children di accedere alle parti sottostanti dell'ora formattata. L'elenco delle parti disponibili è qui.
Props:
props: Intl.DateTimeFormatOptions &
{
value: any,
format: string,
children: (parts: Intl.DateTimeFormatPart[]) => ReactElement,
}
<FormattedTimeParts value={new Date(1459832991883)}> {parts => ( <> <b>{parts[0].value}</b> {parts[1].value} <small>{parts[2].value}</small> </> )} </FormattedTimeParts>
FormattedDateTimeRange
Richiede l'API stage-3 Intl.RelativeTimeFormat.prototype.formatRange con supporto browser limitato. Utilizza il nostro polyfill per aggiungere supporto.
Questo componente utilizza le API formatDateTimeRange e Intl.DateTimeFormat e ha props che corrispondono alle DateTimeFormatOptions specificate sopra.
Props:
props: DateTimeFormatOptions &
{
from: number | Date,
to: number | Date,
children: (formattedDate: string) => ReactElement,
}
Per impostazione predefinita <FormattedDateTimeRange> renderizza l'intervallo temporale formattato in un React.Fragment. Per personalizzare il rendering, è possibile wrapparlo con un altro elemento React (scelta consigliata) o passare una funzione come children.
Esempio:
<FormattedDateTimeRange from={new Date('2020-1-1')} to={new Date('2020-1-15')} />
FormattedRelativeTime
Richiede Intl.RelativeTimeFormat con supporto browser limitato. Utilizza il nostro polyfill per aggiungere supporto.
Questo componente utilizza l'API formatRelativeTime e ha props corrispondenti alle seguenti opzioni di formattazione relativa:
type RelativeTimeFormatOptions = {
numeric?: 'always' | 'auto'
style?: 'long' | 'short' | 'narrow'
}
Tipi di Props:
props: RelativeTimeFormatOptions &
{
value: number,
unit: Unit,
format: string,
updateIntervalInSeconds: number,
children: (formattedDate: string) => ReactElement,
}
Per impostazione predefinita <FormattedRelativeTime> renderizza il tempo relativo formattato in un React.Fragment. Per personalizzare il rendering, è possibile wrapparlo con un altro elemento React (scelta consigliata) o passare una funzione come children.
Esempio:
<FormattedRelativeTime value={0} numeric="auto" updateIntervalInSeconds={1} />
È possibile regolare l'intervallo massimo di ri-render del componente impostando updateIntervalInSeconds. Un valore falsy disattiverà l'aggiornamento automatico. L'aggiornamento è intelligente e pianificherà il prossimo update al prossimo momento significativo.
Un momento significativo è definito come il prossimo value non frazionario per quell'unit. Ad esempio:
<FormattedRelativeTime value={-50} updateIntervalInSeconds={1} />
Inizialmente renderizzerà 59 seconds ago, dopo 1 secondo renderizzerà 1 minute ago e non si aggiornerà finché non passa un minuto intero, quando renderizzerà 2 minutes ago. Non tenterà di renderizzare 1.2 minutes ago.
updateIntervalInSeconds non può essere abilitato per unit superiori a hour (quindi non per day, week, quarter, year). Principalmente perché non avrebbe senso pianificare un timeout in days, e il numero di ms in un giorno supera il timeout massimo accettato da setTimeout.
FormattedNumber
Questo componente utilizza le API formatNumber e Intl.NumberFormat, con props che corrispondono a Intl.NumberFormatOptions.
Props:
props: NumberFormatOptions &
{
value: number,
format: string,
children: (formattedNumber: string) => ReactElement,
}
Per impostazione predefinita <FormattedNumber> renderizza il numero formattato in un React.Fragment. Per personalizzare il rendering, puoi racchiuderlo in un altro elemento React (consigliato) o passare una funzione come child.
Esempio:
<FormattedNumber value={1000} />
Esempio di formattazione valori valutari
<FormattedNumber value={1000} style="currency" currency="USD" />
Formattazione numeri usando unit
Attualmente questa funzionalità fa parte dello standard ES2020 NumberFormat.
Abbiamo fornito un polyfill qui e i tipi di react-intl consentono di passare
unità supportate. Esempio:
<FormattedNumber value={1000} style="unit" unit="kilobyte" unitDisplay="narrow" />
<FormattedNumber value={1000} unit="fahrenheit" unitDisplay="long" style="unit" />
FormattedNumberParts
Richiede Intl.NumberFormat.prototype.formatToParts non disponibile in IE11. Utilizza il nostro polyfill per supportare IE11.
Questo componente offre maggiore personalizzazione rispetto a FormattedNumber, consentendo alla funzione child di accedere alle parti sottostanti del numero formattato. Le parti disponibili sono elencate qui.
Props:
props: NumberFormatOptions &
{
value: number,
format: string,
children: (parts: Intl.NumberFormatPart[]) => ReactElement,
}
Esempio:
<FormattedNumberParts value={1000}> {parts => ( <> <b>{parts[0].value}</b> {parts[1].value} <small>{parts[2].value}</small> </> )} </FormattedNumberParts>
FormattedPlural
Questo componente utilizza l'API formatPlural e Intl.PluralRules, con props che corrispondono a Intl.PluralRulesOptions.
Props:
props: PluralFormatOptions &
{
value: any,
other: ReactElement,
zero: ReactElement,
one: ReactElement,
two: ReactElement,
few: ReactElement,
many: ReactElement,
children: (formattedPlural: ReactElement) => ReactElement,
}
Per impostazione predefinita <FormattedPlural> seleziona una categoria plurale (zero, one, two, few, many, o other) e renderizza il corrispondente elemento React in un React.Fragment. Per personalizzare il rendering, puoi racchiuderlo in un altro elemento React (consigliato) o passare una funzione come child.
Esempio:
<FormattedPlural value={10} one="message" other="messages" />
FormattedList
Richiede Intl.ListFormat con supporto browser limitato. Utilizzare il nostro polyfill se necessario.
Questo componente utilizza l'API formatList e Intl.ListFormat. Le sue proprietà corrispondono a Intl.ListFormatOptions.
Props:
props: ListFormatOptions &
{
children: (chunksOrString: string | React.ReactElement[]) => ReactElement,
}
Esempio:
Con locale en:
<FormattedList type="conjunction" value={['Me', 'myself', 'I']} />
<FormattedList type="conjunction" value={['Me', <b>myself</b>, 'I']} />
FormattedListParts
Richiede Intl.ListFormat con supporto browser limitato. Utilizzare il nostro polyfill se necessario.
Questo componente utilizza l'API formatListToParts e Intl.ListFormat. Le sue proprietà corrispondono a Intl.ListFormatOptions.
Props:
props: ListFormatOptions &
{
children: (chunks: Array<React.ReactElement | string>) => ReactElement,
}
Esempio:
Con locale en:
<FormattedListParts type="conjunction" value={['Me', 'myself', 'I']}> {parts => ( <> <b>{parts[0].value}</b> {parts[1].value} <small>{parts[2].value}</small> {parts[3].value} <small>{parts[4].value}</small> </> )} </FormattedListParts>
FormattedDisplayName
Richiede Intl.DisplayNames con supporto browser limitato. Utilizzare il nostro polyfill se necessario.
Questo componente utilizza formatDisplayName e Intl.DisplayNames. Ha props che corrispondono a DisplayNameOptions. Potrebbe essere necessario un polyfill.
Props:
props: FormatDisplayNameOptions &
{
value: string | number | Record<string, unknown>,
}
Esempio:
Con locale en:
<FormattedDisplayName type="language" value="zh-Hans-SG" />
<FormattedDisplayName type="currency" value="JPY" />
FormattedMessage
Questo componente utilizza l'API formatMessage e ha props che corrispondono a un Message Descriptor.
Props:
props: MessageDescriptor &
{
values: object,
tagName: string,
children: (chunks: ReactElement) => ReactElement,
}
Sintassi dei Messaggi
La formattazione di stringhe/messaggi è funzionalità fondamentale di React Intl, basata sulla ICU Message Formatting tramite la Sintassi Messaggi ICU. Questa sintassi consente di definire messaggi semplici o complessi, tradurli e formattarli a runtime.
Messaggio semplice:
Hello, {name}
Messaggio complesso:
Hello, {name}, you have {itemCount, plural,
=0 {no items}
one {# item}
other {# items}
}.
Vedi: Guida alla sintassi dei messaggi.
Message Descriptor
React Intl utilizza il concetto di Message Descriptor per definire i messaggi predefiniti dell'app. Le proprietà di <FormattedMessage> corrispondono a un Message Descriptor contenente:
-
id: Identificatore univoco e stabile -
description: Contesto per i traduttori sull'uso nell'interfaccia -
defaultMessage: Messaggio predefinito (tipicamente in inglese)
type MessageDescriptor = {
id?: string
defaultMessage?: string
description?: string
}
I pacchetti babel-plugin-formatjs e @formatjs/ts-transformer compilano i Message Descriptor in AST per migliorare le prestazioni.
Fallback nella formattazione messaggi
Le API di formattazione dei messaggi vanno oltre per fornire fallback nelle situazioni comuni in cui la formattazione fallisce; come minimo, dovrebbe sempre essere restituita una stringa non vuota. Ecco l'algoritmo di fallback per la formattazione dei messaggi:
-
Ricerca e formattazione del messaggio tradotto all'
idpassato a<IntlProvider>. -
Fallback alla formattazione del
defaultMessage. -
Fallback al messaggio tradotto nella sorgente dell'
id. -
Fallback alla sorgente del
defaultMessage. -
Fallback all'
idletterale del messaggio.
Utilizzo
Per impostazione predefinita, <FormattedMessage> renderizza la stringa formattata in un <React.Fragment>. Per personalizzare il rendering, puoi:
- Incapsularlo con un altro elemento React (consigliato)
- Specificare un
tagNamediverso (es.'div') - Passare una funzione come figlio
Esempio:
<FormattedMessage id="app.greeting" description="Greeting to welcome the user to the app" defaultMessage="Hello, {name}!" values={{ name: 'Eric', }} />
Esempio: funzione come figlio
<FormattedMessage id="title">{txt => <h1>{txt}</h1>}</FormattedMessage>
I messaggi possono essere stringhe semplici senza segnaposto, il tipo più comune. Questo caso è altamente ottimizzato, ma mantiene i vantaggi della procedura di fallback.
Formattazione Rich Text
<FormattedMessage> supporta anche la formattazione rich-text specificando un tag XML nel messaggio e risolvendolo nella prop values. Esempio:
<FormattedMessage id="app.greeting" description="Greeting to welcome the user to the app" defaultMessage="Hello, <b>Eric</b> {icon}" values={{ b: chunks => <b>{chunks}</b>, icon: <svg />, }} />
Consentendo tag XML incorporati, assicuriamo che le informazioni contestuali non vadano perse quando devi stilizzare parti della stringa. In un esempio più complesso:
<FormattedMessage id="foo" defaultMessage="To buy a shoe, <a>visit our website</a> and <cta>buy a shoe</cta>" values={{ a: chunks => ( <a class="external_link" target="_blank" href="https://www.example.com/shoe" > {chunks} </a> ), cta: chunks => <strong class="important">{chunks}</strong>, }} />
Funzione come figlio
Poiché la formattazione rich-text consente di incorporare ReactElement, nello scenario con funzione come figlio, la funzione riceverà i chunk del messaggio formattato come singolo parametro.
<FormattedMessage id="foo" defaultMessage="To buy a shoe, <a>visit our website</a> and <cta>buy a shoe</cta>" values={{ a: chunks => ( <a class="external_link" target="_blank" href="https://www.example.com/shoe" > {chunks} </a> ), cta: chunks => <strong class="important">{chunks}</strong>, }} > {chunks => <h2>{chunks}</h2>} </FormattedMessage>
Tutto il rich text viene tradotto insieme, producendo output di qualità superiore. Ciò garantisce parità di funzionalità con altre librerie come fluent di Mozilla (usando il concetto di overlays).
Questa estensione consente anche di utilizzare potenzialmente altri formati rich text come Markdown.