Vai al contenuto principale

Componenti

Traduzione Beta Non Ufficiale

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.

attenzione

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:

Live Editor
<FormattedDate value={new Date(1459832991883)} />
Result

Esempio con Opzioni:

Live Editor
<FormattedDate
  value={new Date(1459832991883)}
  year="numeric"
  month="long"
  day="2-digit"
/>
Result

FormattedDateParts

Supporto browser

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,
}
Live Editor
<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>
Result

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:

Live Editor
<FormattedTime value={new Date(1459832991883)} />
Result

FormattedTimeParts

Supporto browser

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,
}
Live Editor
<FormattedTimeParts value={new Date(1459832991883)}>
  {parts => (
    <>
      <b>{parts[0].value}</b>
      {parts[1].value}
      <small>{parts[2].value}</small>
    </>
  )}
</FormattedTimeParts>
Result

FormattedDateTimeRange

Supporto browser

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:

Live Editor
<FormattedDateTimeRange
  from={new Date('2020-1-1')}
  to={new Date('2020-1-15')}
/>
Result

FormattedRelativeTime

Supporto browser

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:

Live Editor
<FormattedRelativeTime value={0} numeric="auto" updateIntervalInSeconds={1} />
Result
intervallo massimo

È 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:

Live Editor
<FormattedRelativeTime value={-50} updateIntervalInSeconds={1} />
Result

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.

limitazione

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:

Live Editor
<FormattedNumber value={1000} />
Result

Esempio di formattazione valori valutari

Live Editor
<FormattedNumber value={1000} style="currency" currency="USD" />
Result

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:

Live Editor
<FormattedNumber
  value={1000}
  style="unit"
  unit="kilobyte"
  unitDisplay="narrow"
/>
Result
Live Editor
<FormattedNumber
  value={1000}
  unit="fahrenheit"
  unitDisplay="long"
  style="unit"
/>
Result

FormattedNumberParts

supporto browser

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:

Live Editor
<FormattedNumberParts value={1000}>
  {parts => (
    <>
      <b>{parts[0].value}</b>
      {parts[1].value}
      <small>{parts[2].value}</small>
    </>
  )}
</FormattedNumberParts>
Result

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:

Live Editor
<FormattedPlural value={10} one="message" other="messages" />
Result

FormattedList

supporto browser

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:

Live Editor
<FormattedList type="conjunction" value={['Me', 'myself', 'I']} />
Result
Live Editor
<FormattedList type="conjunction" value={['Me', <b>myself</b>, 'I']} />
Result

FormattedListParts

supporto browser

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:

Live Editor
<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>
Result

FormattedDisplayName

supporto browser

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:

Live Editor
<FormattedDisplayName type="language" value="zh-Hans-SG" />
Result
Live Editor
<FormattedDisplayName type="currency" value="JPY" />
Result

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
}
compilazione dei descriptor

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:

  1. Ricerca e formattazione del messaggio tradotto all'id passato a <IntlProvider>.

  2. Fallback alla formattazione del defaultMessage.

  3. Fallback al messaggio tradotto nella sorgente dell'id.

  4. Fallback alla sorgente del defaultMessage.

  5. Fallback all'id letterale 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 tagName diverso (es. 'div')
  • Passare una funzione come figlio

Esempio:

Live Editor
<FormattedMessage
  id="app.greeting"
  description="Greeting to welcome the user to the app"
  defaultMessage="Hello, {name}!"
  values={{
    name: 'Eric',
  }}
/>
Result

Esempio: funzione come figlio

Live Editor
<FormattedMessage id="title">{txt => <h1>{txt}</h1>}</FormattedMessage>
Result
messaggio semplice

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:

Live Editor
<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 />,
  }}
/>
Result

Consentendo tag XML incorporati, assicuriamo che le informazioni contestuali non vadano perse quando devi stilizzare parti della stringa. In un esempio più complesso:

Live Editor
<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>,
  }}
/>
Result

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.

Live Editor
<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>
Result

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.