Ir para o conteúdo principal

Guia de Atualização (v1 -> v2)

Tradução Beta Não Oficial

Esta página foi traduzida por PageTurner AI (beta). Não é oficialmente endossada pelo projeto. Encontrou um erro? Reportar problema →

Utilize React 0.14 ou 15

O React Intl v2 possui uma dependência peer em react@^0.14.0 || ^15.0.0-0 e agora aproveita recursos e mudanças do React 0.14, além de ser compatível com o React 15.

Atualize a Forma como os Dados de Localidade são Adicionados

Os módulos de dados de localidade no React Intl v2 foram refatorados para fornecer dados, em vez de modificar o registro interno de dados de localidade do React Intl. Os arquivos react-intl/locale-data/* também estão desacoplados do global ReactIntl e, em vez disso, fornecem módulos UMD com um novo global ReactIntlLocaleData. Essas mudanças significam que os aplicativos precisam atualizar a forma como registram os dados de localidade necessários no navegador.

Adicione a Chamada para addLocaleData() no Navegador

Agora existe uma função addLocaleData() que precisa ser chamada com os dados de localidade carregados. Você pode fazer o seguinte no seu ponto de entrada JavaScript principal do cliente:

Isso pressupõe que um <script> de dados de localidade seja adicionado com base na requisição; por exemplo, para usuários falantes de francês:

<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 Carregar o React Intl

import {addLocaleData} from 'react-intl'

if ('ReactIntlLocaleData' in window) {
Object.keys(ReactIntlLocaleData).forEach(lang => {
addLocaleData(ReactIntlLocaleData[lang])
})
}
informação

Essa desvinculação da biblioteca dos dados de localidade permite que os arquivos sejam carregados via <script async>. Ao usar scripts assíncronos, seu código de inicialização do cliente precisará aguardar o evento load, incluindo o código acima.

Remova o Intl Mixin

O IntlMixin foi removido do React Intl v2. O mixin realizava duas funções: propagava automaticamente locales, formats e messages por toda a hierarquia do aplicativo e fornecia uma API imperativa através das funções format*(). Essas responsabilidades agora são tratadas por <IntlProvider> e injectIntl(), respectivamente:

Atualize para IntlProvider

No React Intl v1, você adicionaria o IntlMixin ao seu componente raiz; por exemplo, <App>. Remova o IntlMixin e, em vez disso, envolva seu componente raiz com <IntlProvider>:

import ReactDOM from 'react-dom'
import {IntlProvider} from 'react-intl'

ReactDOM.render(
<IntlProvider locale="en">
<App />
</IntlProvider>,
document.getElementById('container')
)
informação

A prop locale é singular, obrigatória e aceita apenas valores string. Essa é uma simplificação da prop plural locales usada pelo IntlMixin.

Atualize para injectIntl()

O IntlMixin também fornecia a API imperativa para componentes personalizados usarem os métodos format*(); por exemplo, formatDate() para obter strings formatadas para uso em atributos como title e aria. Remova o IntlMixin e use a função de fábrica de Componente de Ordem Superior (HOC) injectIntl() para injetar a API imperativa via props.

Aqui está um exemplo de um componente stateless personalizado <RelativeTime> que usa injectIntl() e a 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)

O injectIntl() é similar a uma função de fábrica HOC connect() encontrada em frameworks Flux para conectar um componente a uma store.

Mude a Forma como as Mensagens são Formatadas

A forma como mensagens de texto são formatadas no React Intl v2 mudou significativamente! Esse é o conjunto de mudanças mais disruptivo ao atualizar de v1 para v2, mas ele permite muitos novos recursos excelentes.

O React Intl v2 introduz um novo conceito de Message Descriptor que pode ser usado para definir as mensagens padrão de um aplicativo. Um Message Descriptor é um objeto com as seguintes propriedades, sendo id a única prop obrigatória:

  • id: Um identificador único e estável para a mensagem

  • description: Contexto para o tradutor sobre como é usado na interface

  • defaultMessage: A mensagem padrão (provavelmente em inglês)

informação

Este guia de atualização focará em usar Descritores de Mensagem contendo apenas a propriedade id.

Nivelar o Objeto messages

O React Intl v2 não suporta mais objetos messages aninhados. Em vez disso, a coleção de mensagens traduzidas passadas para <IntlProvider> deve ser plana. Esta é uma decisão de projeto explícita que simplifica e aumenta a flexibilidade. O React Intl v2 não aplica semânticas especiais a strings com pontos; por exemplo, "namespaced.string_id".

Aplicativos usando estrutura de objeto messages aninhada podem usar a seguinte função para nivelar seu objeto de acordo com a semântica do 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)
informação

Os ids de mensagem ainda podem conter ".", então os próprios ids permanecem iguais - apenas a estrutura do objeto messages precisa mudar.

Substituir Chamadas getIntlMessage() por Descritores de Mensagem

O método getIntlMessage() fornecido pelo IntlMixin foi removido no React Intl v2. Ele era apenas um helper que interpretava um id de mensagem com "."s pesquisando a mensagem traduzida em um objeto messages aninhado. Com a remoção do IntlMixin e a mudança para um objeto messages plano, este método foi removido.

Todas as chamadas para getIntlMessage() precisam ser substituídas por um Descritor de Mensagem.

Substituir:

this.getIntlMessage('some.message.id')

Por:

{
id: 'some.message.id'
}

Atualizar Chamadas formatMessage()

Um padrão comum ao chamar formatMessage() é aninhar uma chamada para getIntlMessage(). Estas podem ser facilmente atualizadas:

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)
informação

No React Intl v2, a função formatMessage() é injetada via injectIntl().

Atualizar Instâncias de FormattedMessage e FormattedHTMLMessage

As propriedades destes dois componentes mudaram completamente no React Intl v2. Em vez de receber uma prop message e tratar todas outras props como valores para preencher placeholders na mensagem, <FormattedMessage> e <FormattedHTMLMessage> agora têm as mesmas props de um Descritor de Mensagem mais uma nova prop values.

A nova prop values agrupa todos os valores de placeholders da mensagem em um objeto.

O exemplo a seguir mostra como atualizar uma instância de <FormattedMessage> para usar as novas props e remover a chamada para getIntlMessage():

1.0:

<FormattedMessage message={this.getIntlMessage('greeting')} name="Eric" />

2.0:

<FormattedMessage id="greeting" values={{name: 'Eric'}} />

Atualizar a Formatação de Tempos Relativos

Foram feitas pequenas mudanças em como o tempo de referência "now" é especificado ao formatar tempos relativos no React Intl v2. É incomum especificar este valor fora de código de teste, então pode não existir em sua aplicação.

Renomear a Prop now de FormattedRelative para initialNow

Um novo recurso foi adicionado às instâncias de <FormattedRelative> no React Intl v2: elas agora "atualizam" e permanecem em dia. Como o tempo avança, era confuso ter uma prop chamada now, então ela foi renomeada para initialNow. Qualquer instância de <FormattedRelative> usando now deve atualizar o nome da prop para initialNow:

1.0:

<FormattedRelative value={date} now={otherDate} />

2.0:

<FormattedRelative value={date} initialNow={otherDate} />
informação

O componente <IntlProvider> também possui uma propriedade initialNow que pode receber um valor para estabilizar o tempo de referência "now" (agora) para todas as instâncias de <FormattedRelative>. Isso é útil em aplicações universal/isomórficas para garantir checksums React adequados entre a renderização inicial do servidor e do cliente.

Combinar o segundo e terceiro argumentos de formatRelative()

A assinatura da função formatRelative() foi alinhada com as outras funções format*() e na React Intl v2, ela aceita apenas dois argumentos: value e options. Para especificar um tempo de referência "now", adicione-o ao argumento options e remova o terceiro 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,
})
informação

Na React Intl v2, a função formatRelative() é injetada por meio de injectIntl().