Guida all'aggiornamento (da v1 a v2)
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
Usa React 0.14 o 15
React Intl v2 ha una dipendenza peer su react@^0.14.0 || ^15.0.0-0 e ora sfrutta le funzionalità e i cambiamenti di React 0.14, funzionando anche con React 15.
Aggiorna come vengono aggiunti i dati di localizzazione
I moduli di dati di localizzazione in React Intl v2 sono stati rifattorizzati per fornire dati, invece di mutare il registro interno dei dati di localizzazione di React Intl. I file react-intl/locale-data/* sono inoltre disaccoppiati dalla variabile globale ReactIntl e forniscono invece moduli UMD con una nuova variabile globale ReactIntlLocaleData. Questi cambiamenti implicano che le applicazioni debbano aggiornare il modo in cui registrano i dati di localizzazione necessari nel browser.
Aggiungi la chiamata a addLocaleData() nel browser
Ora esiste una funzione addLocaleData() che deve essere chiamata con i dati di localizzazione caricati. Puoi procedere come segue nel tuo punto di ingresso principale del client JavaScript:
Questo presuppone che un tag <script> per i dati di localizzazione venga aggiunto in base alla richiesta; ad esempio, per utenti francofoni:
<script src="react-intl/locale-data/fr.js"></script>
Utilizzo di <script src="react-intl/dist/react-intl.js>
if ('ReactIntl' in window && 'ReactIntlLocaleData' in window) {
Object.keys(ReactIntlLocaleData).forEach(lang => {
ReactIntl.addLocaleData(ReactIntlLocaleData[lang])
})
}
Utilizzo di Browserify/Webpack per caricare React Intl
import {addLocaleData} from 'react-intl'
if ('ReactIntlLocaleData' in window) {
Object.keys(ReactIntlLocaleData).forEach(lang => {
addLocaleData(ReactIntlLocaleData[lang])
})
}
Questo disaccoppiamento della libreria dai dati di localizzazione consente di caricare i file tramite <script async>. Quando si utilizzano script asincroni, il codice di bootstrap del client dovrà attendere l'evento load, incluso il codice sopra.
Rimuovi il mixin Intl
L'IntlMixin è stato rimosso da React Intl v2. Il mixin svolgeva due funzioni: propagava automaticamente locales, formats e messages in tutta la gerarchia dell'applicazione e forniva un'API imperativa tramite funzioni format*(). Questi compiti sono ora gestiti rispettivamente da <IntlProvider> e injectIntl():
Aggiorna a IntlProvider
In React Intl v1, si aggiungeva l'IntlMixin al componente radice; ad esempio, <App>. Rimuovi l'IntlMixin e avvolgi invece il tuo componente radice con <IntlProvider>:
import ReactDOM from 'react-dom'
import {IntlProvider} from 'react-intl'
ReactDOM.render(
<IntlProvider locale="en">
<App />
</IntlProvider>,
document.getElementById('container')
)
La prop locale è singolare, obbligatoria e accetta solo un valore stringa. Questa è una semplificazione della prop plurale locales utilizzata dall'IntlMixin.
Aggiorna a injectIntl()
L'IntlMixin forniva anche l'API imperativa per consentire ai componenti personalizzati di utilizzare i metodi format*(); ad esempio, formatDate() per ottenere stringhe formattate da utilizzare in attributi come title e aria. Rimuovi l'IntlMixin e utilizza invece la funzione factory HOC injectIntl() per iniettare l'API imperativa tramite props.
Ecco un esempio di componente senza stato personalizzato <RelativeTime> che utilizza injectIntl() e l'API imperativa formatDate():
import React from 'react'
import {injectIntl, FormattedRelative} from 'react-intl'
const to2Digits = num => `${num < 10 ? `0${num}` : num}`
const RelativeTime = ({date, intl}) => {
date = new Date(date)
let year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
let formattedDate = intl.formatDate(date, {
year: 'long',
month: 'numeric',
day: 'numeric',
})
return (
<time
dateTime={`${year}-${to2Digits(month)}-${to2Digits(day)}`}
title={formattedDate}
>
<FormattedRelative value={date} />
</time>
)
}
export default injectIntl(RelativeTime)
injectIntl() è simile a una funzione factory HOC connect() che potresti trovare in un framework Flux per connettere un componente a uno store.
Cambia come vengono formattati i messaggi
Il modo in cui i messaggi stringa vengono formattati in React Intl v2 è cambiato significativamente! Questa è la serie di cambiamenti più dirompente durante l'aggiornamento da v1 a v2, ma abilita molte nuove e ottime funzionalità.
React Intl v2 introduce un nuovo concetto di Message Descriptor che può essere utilizzato per definire i messaggi stringa predefiniti di un'applicazione. Un Message Descriptor è un oggetto con le seguenti proprietà, dove id è l'unica prop obbligatoria:
-
id: Un identificatore univoco e stabile per il messaggio -
description: Contesto per il traduttore sull'utilizzo nell'interfaccia utente -
defaultMessage: Il messaggio predefinito (probabilmente in inglese)
Questa guida all'aggiornamento si concentrerà sull'uso di Message Descriptor contenenti solo la proprietà id.
Appiattire l'oggetto messages
React Intl v2 non supporta più oggetti messages annidati. La raccolta di messaggi tradotti passata a <IntlProvider> deve essere piatta. Questa scelta progettuale esplicita semplifica la struttura aumentando la flessibilità. React Intl v2 non applica semantiche speciali alle stringhe con punti; es. "namespaced.string_id".
Le applicazioni che utilizzano strutture annidate per l'oggetto messages possono usare questa funzione per appiattirlo secondo la semantica di React Intl v1:
function flattenMessages(nestedMessages, prefix = '') {
return Object.keys(nestedMessages).reduce((messages, key) => {
let value = nestedMessages[key]
let prefixedKey = prefix ? `${prefix}.${key}` : key
if (typeof value === 'string') {
messages[prefixedKey] = value
} else {
Object.assign(messages, flattenMessages(value, prefixedKey))
}
return messages
}, {})
}
let messages = flattenMessages(nestedMessages)
Gli ID messaggio possono comunque contenere punti ".", quindi gli ID rimangono identici. Cambia solo la struttura dell'oggetto messages.
Sostituire le chiamate getIntlMessage() con Message Descriptor
Il metodo getIntlMessage() fornito da IntlMixin è stato rimosso in React Intl v2. Era un helper che interpretava gli ID messaggio contenenti "." cercando il messaggio tradotto in un oggetto messages annidato. Con la rimozione di IntlMixin e il passaggio a un oggetto messages piatto, questo metodo è stato eliminato.
Tutte le chiamate a getIntlMessage() devono essere sostituite con un Message Descriptor.
Sostituire:
this.getIntlMessage('some.message.id')
Con:
{
id: 'some.message.id'
}
Aggiornare le chiamate formatMessage()
Un pattern comune prevedeva di annidare getIntlMessage() dentro formatMessage(). Ecco come aggiornare:
1.0:
let message = this.formatMessage(this.getIntlMessage('some.message.id'), values)
2.0:
let message = this.props.intl.formatMessage({id: 'some.message.id'}, values)
In React Intl v2, la funzione formatMessage() viene iniettata tramite injectIntl().
Aggiornare le istanze di FormattedMessage e FormattedHTMLMessage
Le proprietà di questi componenti sono completamente cambiate in v2. Invece di accettare una prop message e trattare altre proprietà come valori per riempire i segnaposto, ora <FormattedMessage> e <FormattedHTMLMessage> accettano le stesse proprietà di un Message Descriptor più una nuova prop values.
La nuova prop values raggruppa tutti i valori dei segnaposto in un oggetto.
Questo esempio mostra come aggiornare un'istanza di <FormattedMessage> usando le nuove proprietà ed eliminando getIntlMessage():
1.0:
<FormattedMessage message={this.getIntlMessage('greeting')} name="Eric" />
2.0:
<FormattedMessage id="greeting" values={{name: 'Eric'}} />
Aggiornare la formattazione degli orari relativi
Sono state apportate modifiche minori alla specifica del tempo di riferimento "now" nella formattazione degli orari relativi in v2. È raro specificare questo valore al di fuori dei test, quindi potrebbe non essere presente nella tua applicazione.
Rinominare la prop now di FormattedRelative in initialNow
React Intl v2 aggiunge una nuova funzionalità alle istanze di <FormattedRelative>: ora "ticchettano" mantenendosi aggiornate. Dato che il tempo avanza, la prop now risultava confusa ed è stata rinominata initialNow. Qualsiasi istanza di <FormattedRelative> che utilizza now dovrebbe aggiornare il nome della prop a initialNow:
1.0:
<FormattedRelative value={date} now={otherDate} />
2.0:
<FormattedRelative value={date} initialNow={otherDate} />
Il componente <IntlProvider> dispone anche di una prop initialNow a cui può essere assegnato un valore per stabilizzare il tempo di riferimento "now" per tutte le istanze <FormattedRelative>. Ciò è utile nelle applicazioni universali/isomorfe per garantire checksum React corretti tra il rendering iniziale server e client.
Unisci secondo e terzo argomento di formatRelative()
La firma della funzione formatRelative() è stata allineata alle altre funzioni format*(): in React Intl v2 accetta solo due argomenti (value e options). Per specificare un tempo di riferimento "now", aggiungilo all'argomento options rimuovendo il terzo argomento formatOptions:
1.0:
let relative = this.formatRelative(date, {units: 'hour'}, {now: otherDate})
2.0:
let relative = this.props.intl.formatRelative(date, {
units: 'hour',
now: otherDate,
})
In React Intl v2, la funzione formatRelative() viene iniettata tramite injectIntl().