Vai al contenuto principale

Panoramica

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

npm Version

Benvenuti nella documentazione di React Intl! Qui troverete la documentazione di React Intl. Sentitevi liberi di aprire una pull request e contribuire alla documentazione per migliorarla.

Requisiti di Runtime

Supportiamo IE11 e le 2 versioni più recenti di Edge, Chrome, Firefox e Safari.

React Intl si basa su queste API Intl:

Se devi supportare browser più vecchi, ti consigliamo di procedere come segue:

  1. Se supporti browser senza Intl, includi questo polyfill nel tuo build.

  2. Applica un polyfill per Intl.NumberFormat con @formatjs/intl-numberformat.

  3. Applica un polyfill per Intl.DateTimeFormat con @formatjs/intl-datetimeformat

  4. Se supporti browser senza Intl.PluralRules (es. IE11 e Safari 12-), includi questo polyfill nel tuo build.

  5. Se supporti browser senza Intl.RelativeTimeFormat (es. IE11, Edge, Safari 12-), includi questo polyfill nel tuo build insieme ai dati CLDR specifici per ogni lingua supportata.

  6. Se hai bisogno di Intl.DisplayNames, includi questo polyfill nel tuo build insieme ai dati CLDR specifici per ogni lingua supportata.

Node.js

full-icu

A partire da Node.js 13.0.0, full-icu è supportato di default.

Se utilizzi React Intl in versioni precedenti di Node.js, il tuo binario node deve:

  • Essere compilato con full-icu seguendo queste istruzioni

OPPURE

Se la tua versione di node non include alcune delle API Intl sopra elencate, dovrai polyfillarle di conseguenza.

React Native

Se utilizzi react-intl in React Native, assicurati che il tuo runtime abbia supporto Intl integrato (simile alla variante internazionale di JSC). Consulta questi issue per maggiori dettagli:

React Native su iOS

Se non puoi usare la variante Intl di JSC (es. su iOS), segui le istruzioni in Requisiti di Runtime per applicare i polyfill a queste API.

Il pacchetto react-intl

Installa il pacchetto npm react-intl via npm:

npm i -S react-intl

Il pacchetto npm react-intl distribuisce i seguenti moduli (link da unpkg):

  • CommonJS: dipendenze non bundle, "main" in package.json, avvisi in dev.

  • ES6: dipendenze non bundle, "module" in package.json, avvisi in dev.

Bundler di Moduli

Abbiamo ottimizzato React Intl per funzionare con bundler come Browserify, Webpack o Rollup, che possono creare il bundle di React Intl per il browser:

  • Il campo "browser" in package.json è configurato per includere solo i dati di localizzazione inglese di base durante il bundling. In questo modo, usando il modulo "main" in Node vengono caricati tutti i dati di localizzazione, ma sono ignorati quando in bundle per il browser.

  • Una versione ES6 di React Intl è fornita come "jsnext:main" e "module" in package.json e può essere usata con Rollup.

  • Gli avvisi in fase di sviluppo sono racchiusi in process.env.NODE_ENV !== 'production', consentendo di specificare NODE_ENV durante il bundling e la minificazione per rimuovere questi blocchi di codice.

Il modulo React Intl

Sia che utilizzi la versione ES6, CommonJS o UMD di React Intl, tutte forniscono le stesse esportazioni denominate:

react

Quando si utilizza la versione UMD di React Intl senza un sistema di moduli, si aspetterà che react esista nella variabile globale: React, e inserirà le esportazioni denominate sopra nella variabile globale: ReactIntl.

Creazione di un contesto I18n

Ora con React Intl e i suoi dati di localizzazione caricati, è possibile creare un contesto i18n per la tua app React.

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 usare il componente <IntlProvider>.

L'utilizzo più comune consiste nell'avvolgere il componente radice di React con <IntlProvider> configurandolo con la località corrente dell'utente e le corrispondenti stringhe/messaggi tradotti:

ReactDOM.render(
<IntlProvider locale={usersLocale} messages={translationsForUsersLocale}>
<App />
</IntlProvider>,
document.getElementById('container')
)

Vedi: la documentazione di <IntlProvider> per maggiori dettagli.

Formattazione dei dati

React Intl offre due modi per formattare i dati: tramite componenti React e la sua API. I componenti forniscono un modo idiomatico-React per integrare l'internazionalizzazione in un'app React, e i componenti <Formatted*> offrono vantaggi rispetto all'uso diretto dell'API imperativa. L'API dovrebbe essere utilizzata quando il componente React deve formattare dati in un valore stringa dove un elemento React non è adatto; ad esempio, un attributo title o aria, o per effetti collaterali in componentDidMount.

L'API imperativa di React Intl è accessibile tramite injectIntl, una factory di Higher-Order Component (HOC). Avvolgerà il componente React passato con un altro componente React che fornisce l'API di formattazione imperativa al componente avvolto tramite le sue props. (Questo è simile al pattern connect-to-stores presente in molte implementazioni Flux.)

Ecco un esempio che utilizza <IntlProvider>, i componenti <Formatted*>, e l'API imperativa per configurare un contesto i18n e formattare dati:

import React from 'react';
import ReactDOM from 'react-dom';
import {IntlProvider, FormattedRelative, useIntl} from 'react-intl';

const MS_IN_DAY = 1e3 * 3600 * 24

const PostDate = ({date}) => {
const intl = useIntl()
return (
<span title={intl.formatDate(date)}>
<FormattedRelativeTime value={(Date.now() - date)/MS_IN_DAY} unit="day"/>
</span>
)
});

const App = ({post}) => (
<div>
<h1>{post.title}</h1>
<p>
<PostDate date={post.date} />
</p>
<div>{post.body}</div>
</div>
);

ReactDOM.render(
<IntlProvider locale={navigator.language}>
<App
post={{
title: 'Hello, World!',
date: new Date(1459913574887),
body: 'Amazing content.',
}}
/>
</IntlProvider>,
document.getElementById('container')
);

Assumendo che navigator.language sia "en-us":

<div>
<h1>Hello, World!</h1>
<p><span title="4/5/2016">yesterday</span></p>
<div>Amazing content.</div>
</div>

Vedi: la documentazione delle API e dei Componenti per maggiori dettagli.

Build ESM

react-intl e le sue librerie sottostanti (@formatjs/icu-messageformat-parser, intl-messageformat, @formatjs/intl-relativetimeformat) esportano artefatti ESM. Ciò significa che dovresti configurare la tua toolchain di build per transpilarle.

Jest

Aggiungi transformIgnorePatterns per includere sempre queste librerie, ad esempio:

{
transformIgnorePatterns: [
'/node_modules/(?!intl-messageformat|@formatjs/icu-messageformat-parser).+\\.js$',
],
}

webpack

Se utilizzi babel-loader o ts-loader, puoi scegliere una di queste opzioni:

  1. Aggiungi queste librerie in include:
{
include: [
path.join(__dirname, 'node_modules/react-intl'),
path.join(__dirname, 'node_modules/intl-messageformat'),
path.join(__dirname, 'node_modules/@formatjs/icu-messageformat-parser'),
]
}

OPPURE

  1. Aggiungi queste librerie in exclude:
exclude: /node_modules\/(?!react-intl|intl-messageformat|@formatjs\/icu-messageformat-parser)/,

Concetti Fondamentali

  • Formattatori (Data, Numero, Messaggio, Relativo)

  • Provider e Injector

  • API e Componenti

  • Message Descriptor

  • Sintassi dei Messaggi

  • Definire messaggi predefiniti per l'estrazione

  • Formati personalizzati con nome

Applicazioni di Esempio

Diverse applicazioni eseguibili di esempio sono presenti in questa repository Git. Sono un ottimo modo per vedere in azione i concetti fondamentali di React Intl in applicazioni semplificate.

Riferimento API

React Intl fornisce e si basa su diversi livelli API. Utilizzando React Intl interagirai con API Intl native, l'API di React Intl e i suoi componenti React:

Utilizzo con TypeScript

react-intl è scritto in TypeScript, offrendo quindi supporto di prima classe per TS.

Per utilizzare react-intl con TypeScript, assicurati che la configurazione lib in compilerOptions includa ["esnext.intl", "es2017.intl", "es2018.intl"].

Tipizzazione degli ID messaggio e delle locali

Per impostazione predefinita, il tipo della prop id in <FormattedMessage> e formatMessage è string. Tuttavia, puoi impostare un tipo più restrittivo per ottenere autocompletamento e controllo degli errori. Per farlo, sovrascrivi il seguente namespace globale con il tipo unione di tutti i tuoi ID messaggio. Includi da qualche parte nel tuo codice:

declare global {
namespace FormatjsIntl {
interface Message {
ids: keyof typeof messages
}
}
}

Dove messages è l'oggetto che normalmente passeresti a <IntlProvider>, ad esempio:

const messages = {
greeting: 'Hello',
planet: 'World',
// ...
}

Puoi anche sovrascrivere il seguente globale per utilizzare un tipo personalizzato per le locali:

declare global {
namespace FormatjsIntl {
interface IntlConfig {
locale: 'en' | 'fr'
}
}
}

Tipizzazione dei formati personalizzati

Per impostazione predefinita, il tipo della prop format per <FormattedDate>, <FormattedDateParts>, <FormattedTime> e <FormattedTimeParts> è string. Lo stesso vale per la configurazione format di formatDate, formatDateParts, formatTime e formatTimeParts. Tuttavia, puoi impostare un tipo più restrittivo per ottenere autocompletamento e controllo degli errori. Per farlo, sovrascrivi il seguente namespace globale con il tipo unione di tutti i nomi dei tuoi formati personalizzati. Puoi farlo includendo da qualche parte nel tuo codice:

declare global {
namespace FormatjsIntl {
interface Formats {
date: keyof (typeof customFormats)['date']
time: keyof (typeof customFormats)['time']
}
}
}

Dove customFormats è l'oggetto che normalmente passeresti a <IntlProvider>, e avrebbe un aspetto simile a:

const customFormats = {
date: {
short: {
month: 'numeric',
day: 'numeric',
year: '2-digit',
},
},
time: {
short: {
hour: 'numeric',
minute: 'numeric',
},
},
}

Utilizzo Avanzato

La nostra sezione Utilizzo Avanzato contiene guide aggiuntive per configurazioni di produzione in ambienti dove le prestazioni sono cruciali.

Tooling Supportato

Estrazione messaggi

Abbiamo sviluppato @formatjs/cli che aiuta ad estrarre messaggi da una lista di file. Utilizza internamente babel-plugin-formatjs e può estrarre messaggi se li dichiari con uno di questi meccanismi:

import {defineMessages} from 'react-intl'

defineMessages({
foo: {
id: 'foo',
defaultMessage: 'foo',
description: 'bar',
},
})
import {FormattedMessage} from 'react-intl'
;<FormattedMessage id="foo" defaultMessage="foo" description="bar" />
function Comp(props) {
const {intl} = props
return intl.formatMessage({
// The whole `intl.formatMessage` is required so we can extract
id: 'foo',
defaultMessage: 'foo',
description: 'bar',
})
}

Plugin ESLint

Abbiamo anche creato eslint-plugin-formatjs che aiuta a far rispettare regole specifiche sui messaggi se il tuo fornitore di traduzioni ha restrizioni.