Guía de actualización (v1 a v2)
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Usar React 0.14 o 15
React Intl v2 tiene una dependencia peer en react@^0.14.0 || ^15.0.0-0 y aprovecha características y cambios de React 0.14, además de funcionar con React 15.
Actualizar cómo se añaden los datos de configuración regional
Los módulos de datos regionales en React Intl v2 se han refactorizado para proporcionar datos, en lugar de mutar el registro interno de datos regionales de React Intl. Los archivos react-intl/locale-data/* también están desacoplados del global ReactIntl y en su lugar proporcionan módulos UMD con un nuevo global ReactIntlLocaleData. Estos cambios implican que las aplicaciones deben actualizar cómo registran los datos regionales necesarios en el navegador.
Añadir llamada a addLocaleData() en el navegador
Ahora existe una función addLocaleData() que debe llamarse con los datos regionales cargados. Puedes hacer lo siguiente en tu punto de entrada principal de JavaScript cliente:
Esto asume que se añade un <script> de datos regionales basado en la solicitud; por ejemplo, para usuarios francófonos:
<script src="react-intl/locale-data/fr.js"></script>
Usando <script src="react-intl/dist/react-intl.js>
if ('ReactIntl' in window && 'ReactIntlLocaleData' in window) {
Object.keys(ReactIntlLocaleData).forEach(lang => {
ReactIntl.addLocaleData(ReactIntlLocaleData[lang])
})
}
Usando Browserify/Webpack para cargar React Intl
import {addLocaleData} from 'react-intl'
if ('ReactIntlLocaleData' in window) {
Object.keys(ReactIntlLocaleData).forEach(lang => {
addLocaleData(ReactIntlLocaleData[lang])
})
}
Este desacoplamiento de la biblioteca de los datos regionales permite cargar los archivos mediante <script async>. Al usar scripts asíncronos, tu código de inicialización del cliente deberá esperar al evento load, incluyendo el código anterior.
Eliminar Intl Mixin
Se ha eliminado IntlMixin en React Intl v2. El mixin realizaba dos funciones: propagaba automáticamente locales, formats y messages en la jerarquía de la aplicación, y proporcionaba una API imperativa mediante funciones format*(). Estas tareas ahora las manejan <IntlProvider> e injectIntl(), respectivamente:
Actualizar a IntlProvider
En React Intl v1, añadías IntlMixin a tu componente raíz; por ejemplo, <App>. Elimina IntlMixin y en su lugar envuelve tu componente raíz 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 es singular, obligatoria y solo acepta valores de cadena. Esta es una simplificación de la prop plural locales usada por IntlMixin.
Actualizar a injectIntl()
IntlMixin también proporcionaba la API imperativa para que componentes personalizados usaran los métodos format*(); por ejemplo, formatDate() para obtener cadenas formateadas para usar en lugares como atributos title y aria. Elimina IntlMixin y usa en su lugar la función factoría de componentes de orden superior (HOC) injectIntl() para inyectar la API imperativa mediante props.
Aquí un ejemplo de un componente sin estado <RelativeTime> que usa injectIntl() y la 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() es similar a una función factoría HOC connect() que encontrarías en un framework Flux para conectar un componente a un almacén.
Cambiar cómo se formatean los mensajes
¡La forma de formatear mensajes de cadena en React Intl v2 ha cambiado significativamente! Este es el conjunto de cambios más disruptivo al actualizar de v1 a v2, pero habilita nuevas características importantes.
React Intl v2 introduce un nuevo concepto de Descriptor de Mensaje que puede usarse para definir los mensajes de cadena predeterminados de una aplicación. Un Descriptor de Mensaje es un objeto con las siguientes propiedades, siendo id la única obligatoria:
-
id: Un identificador único y estable para el mensaje -
description: Contexto para el traductor sobre cómo se usa en la interfaz -
defaultMessage: El mensaje predeterminado (probablemente en inglés)
Esta guía de actualización se enfocará en usar Descriptores de Mensaje que solo contengan la propiedad id.
Aplanar el objeto messages
React Intl v2 ya no admite objetos messages anidados. En su lugar, la colección de mensajes traducidos pasada a <IntlProvider> debe ser plana. Esta es una decisión de diseño explícita que simplifica y aumenta la flexibilidad. React Intl v2 no aplica ninguna semántica especial a cadenas con puntos; ej. "namespaced.string_id".
Las aplicaciones que usan estructuras de objetos messages anidadas pueden usar la siguiente función para aplanar su objeto según la semántica de 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)
Los ids de mensaje aún pueden contener ".", por lo que los ids en sí permanecen iguales. Solo cambia la estructura del objeto messages.
Reemplazar llamadas a getIntlMessage() con Descriptores de Mensaje
El método getIntlMessage() proporcionado por IntlMixin se eliminó en React Intl v2. Era simplemente un helper que interpretaba un id de mensaje con "." buscando el mensaje traducido en un objeto messages anidado. Con la eliminación de IntlMixin y el cambio a un objeto messages plano, este método se eliminó.
Todas las llamadas a getIntlMessage() deben reemplazarse con un Descriptor de Mensaje.
Reemplazar:
this.getIntlMessage('some.message.id')
Con:
{
id: 'some.message.id'
}
Actualizar llamadas a formatMessage()
Un patrón típico al llamar a formatMessage() es anidar una llamada a getIntlMessage(). Estas pueden actualizarse fácilmente:
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)
En React Intl v2, la función formatMessage() se inyecta mediante injectIntl().
Actualizar instancias de FormattedMessage y FormattedHTMLMessage
Las props para estos dos componentes cambiaron completamente en React Intl v2. En lugar de tomar una prop message y tratar todas las demás props como valores para rellenar marcadores de posición, <FormattedMessage> y <FormattedHTMLMessage> ahora toman las mismas props que un Descriptor de Mensaje más una nueva prop values.
La nueva prop values agrupa todos los valores de los marcadores de posición del mensaje en un objeto.
El siguiente ejemplo muestra cómo actualizar una instancia de <FormattedMessage> para usar las nuevas props y eliminar la llamada a getIntlMessage():
1.0:
<FormattedMessage message={this.getIntlMessage('greeting')} name="Eric" />
2.0:
<FormattedMessage id="greeting" values={{name: 'Eric'}} />
Actualizar el formato de tiempos relativos
Se realizaron cambios menores en cómo se especifica el tiempo de referencia "now" al formatear tiempos relativos en React Intl v2. Es poco común especificar este valor fuera de código de prueba, por lo que podría no existir en tu aplicación.
Renombrar la prop now de FormattedRelative a initialNow
Se agregó una nueva característica a las instancias de <FormattedRelative> en React Intl v2: ahora "actualizan" y se mantienen al día. Como el tiempo avanza, era confuso tener una prop llamada now, por lo que se renombró a initialNow. Cualquier instancia de <FormattedRelative> que use now debe actualizar el nombre de la prop a initialNow:
1.0:
<FormattedRelative value={date} now={otherDate} />
2.0:
<FormattedRelative value={date} initialNow={otherDate} />
El componente <IntlProvider> también tiene una propiedad initialNow que puede asignarse para estabilizar el tiempo de referencia "now" en todas las instancias de <FormattedRelative>. Esto es útil para aplicaciones universales/isomórficas para garantizar checksums de React consistentes entre el renderizado inicial del servidor y del cliente.
Combinar el segundo y tercer argumento de formatRelative()
La firma de la función formatRelative() se ha alineado con las demás funciones format*(). En React Intl v2, solo acepta dos argumentos: value y options. Para especificar un tiempo de referencia "now", agrégalo al argumento options y elimina el tercer argumento 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,
})
En React Intl v2, la función formatRelative() se inyecta mediante injectIntl().