Saltar al contenido principal

Componentes

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

React Intl incluye un conjunto de componentes React que proporcionan una forma declarativa de configurar un contexto de i18n y formatear fechas, números y cadenas para mostrarlos en una interfaz web. Estos componentes renderizan elementos React aprovechando la API imperativa de React Intl.

¿Por qué componentes?

Además de ofrecer una forma idiomática de React para integrar internacionalización en aplicaciones, los componentes <Formatted*> tienen ventajas sobre el uso directo de la API imperativa:

  • Renderizan elementos React que se integran perfectamente con otros componentes.

  • Soportan formato de texto enriquecido en mensajes/cadenas con <FormattedMessage>.

  • Implementan características avanzadas como la actualización automática de <FormattedRelativeTime>.

  • Proporcionan definiciones de tipos para TypeScript.

IntlProvider

React Intl utiliza el patrón proveedor para delimitar un contexto de i18n a un árbol de componentes. Esto permite configurar propiedades como la localización actual y mensajes traducidos en la raíz del árbol, haciéndolos disponibles para los componentes <Formatted*>. Es el mismo concepto que frameworks Flux como Redux usan para proporcionar acceso a un store.

precaución

Todas las apps que usan React Intl deben utilizar <IntlProvider> o <RawIntlProvider>.

Este componente configura el contexto de i18n para un árbol. Normalmente envuelve el componente raíz de la aplicación para que todo el árbol esté dentro del contexto de i18n configurado. Estas son las propiedades de configuración disponibles:

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 y messages

La localización actual del usuario y en qué debe renderizarse la aplicación. Mientras que defaultLocale y defaultFormats son para fallbacks o durante desarrollo, representando los valores predeterminados de la aplicación. Observa que no hay defaultMessages, porque cada Descriptor de Mensaje proporciona un defaultMessage.

defaultLocale y defaultFormats

Localización y formatos predeterminados para cuando un mensaje no está traducido (ausente en messages). defaultLocale debe ser la localización donde se declaran los defaultMessage para que una oración sea coherente en un único idioma. Sin defaultLocale o si está configurado incorrectamente, podrías encontrarte con escenarios donde una oración está en inglés pero las fechas/horas incrustadas están en español.

textComponent

Permite configurar el contenedor predeterminado para componentes <Formatted*>. Si no se especifica, se usa <React.Fragment>. Antes de V3 se usaba span; consulta la guía de migración para más detalles.

onError

Permite al usuario proporcionar un manejador de errores personalizado. Por defecto, los mensajes de error se registran con console.error si NODE_ENV no está configurado como production.

onWarn

Permite definir un manejador personalizado para advertencias. Por defecto, los mensajes se registran con console.warning cuando NODE_ENV no es production.

wrapRichTextChunksInFragment

Al formatear mensajes de texto enriquecido, la salida es de tipo Array<string | React.ReactElement>, lo que puede causar errores de keys. Esta opción envuelve el resultado en un único React.Fragment para evitarlo.

defaultRichTextElements

Un mapa de etiqueta a función de formateo de texto enriquecido. Su propósito es centralizar el formateo de etiquetas comunes como <b>, <p>... o imponer cierto Design System en el código (ej: <a> o <button> estandarizados). Consulta https://github.com/formatjs/formatjs/issues/1752 para más contexto.

Estas propiedades se combinan con las específicas de <IntlProvider>:

Props:

props: IntlConfig &
{
children: ReactNode,
}

Es obligatorio proporcionar elementos hijos a <IntlProvider>.

Ejemplo:

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')
)

Suponiendo que navigator.language es "fr":

<div>mardi 5 avril 2016</div>

RawIntlProvider

Es el objeto React.Context.Provider subyacente que usa IntlProvider. Puede utilizarse 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

Este componente usa las APIs formatDate e Intl.DateTimeFormat, y tiene props que corresponden a las DateTimeFormatOptions especificadas anteriormente.

Props:

props: Intl.DateTimeFormatOptions &
{
value: any,
format: string,
children: (formattedDate: string) => ReactElement,
}

Por defecto, <FormattedDate> renderiza la fecha formateada en un <React.Fragment>. Para personalizar el renderizado, puedes envolverlo con otro elemento React (recomendado) o pasar una función como children.

Ejemplo:

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

Ejemplo con opciones:

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

FormattedDateParts

soporte del navegador

Esto requiere Intl.DateTimeFormat.prototype.formatToParts que no está disponible en IE11. Por favor, usa nuestro polyfill si planeas dar soporte a IE11.

Este componente ofrece mayor personalización de FormattedDate al permitir que la función children acceda a las partes subyacentes de la fecha formateada. Las partes disponibles se listan aquí

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

Este componente utiliza las APIs formatTime y Intl.DateTimeFormat y tiene props que corresponden a las DateTimeFormatOptions especificadas anteriormente, con los siguientes valores predeterminados:

{
hour: 'numeric',
minute: 'numeric',
}

Props:

props: DateTimeFormatOptions &
{
value: any,
format: string,
children: (formattedDate: string) => ReactElement,
}

Por defecto, <FormattedTime> renderizará la hora formateada en un React.Fragment. Si necesitas personalizar el renderizado, puedes envolverlo con otro elemento React (recomendado) o pasar una función como children.

Ejemplo:

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

FormattedTimeParts

soporte del navegador

Esto requiere Intl.DateTimeFormat.prototype.formatToParts que no está disponible en IE11. Por favor, usa nuestro polyfill si planeas dar soporte a IE11.

Este componente ofrece mayor personalización de FormattedTime al permitir que la función children acceda a las partes subyacentes de la hora formateada. Las partes disponibles se listan aquí

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

soporte del navegador

Esto requiere la API en etapa 3 Intl.RelativeTimeFormat.prototype.formatRange que tiene soporte limitado en navegadores. Por favor, usa nuestro polyfill si planeas darles soporte.

Este componente utiliza las APIs formatDateTimeRange y Intl.DateTimeFormat y tiene props que corresponden a las DateTimeFormatOptions especificadas anteriormente

Props:

props: DateTimeFormatOptions &
{
from: number | Date,
to: number | Date,
children: (formattedDate: string) => ReactElement,
}

Por defecto, <FormattedDateTimeRange> renderizará el rango de fecha y hora formateado en un React.Fragment. Si necesitas personalizar el renderizado, puedes envolverlo con otro elemento React (recomendado) o pasar una función como children.

Ejemplo:

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

FormattedRelativeTime

soporte del navegador

Esto requiere Intl.RelativeTimeFormat que tiene soporte limitado en navegadores. Por favor, usa nuestro polyfill si planeas darles soporte.

Este componente utiliza la API formatRelativeTime y tiene props que corresponden a las siguientes opciones de formato relativo:

type RelativeTimeFormatOptions = {
numeric?: 'always' | 'auto'
style?: 'long' | 'short' | 'narrow'
}

Tipos de Props:

props: RelativeTimeFormatOptions &
{
value: number,
unit: Unit,
format: string,
updateIntervalInSeconds: number,
children: (formattedDate: string) => ReactElement,
}

Por defecto, <FormattedRelativeTime> renderizará el tiempo relativo formateado en un React.Fragment. Si necesitas personalizar el renderizado, puedes envolverlo con otro elemento React (recomendado) o pasar una función como children.

Ejemplo:

Live Editor
<FormattedRelativeTime value={0} numeric="auto" updateIntervalInSeconds={1} />
Result
intervalo máximo

Puedes ajustar el intervalo máximo de rerenderizado del componente configurando updateIntervalInSeconds. Un valor falsy desactivará la actualización automática. La actualización es inteligente y programará la próxima actualización para el próximo momento interesante.

Un momento interesante se define como el siguiente value no fraccional para esa unit. Por ejemplo:

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

Inicialmente renderizará 59 seconds ago, después de 1 segundo, renderizará 1 minute ago, y no volverá a renderizar hasta que pase un minuto completo, entonces mostrará 2 minutes ago. No intentará renderizar 1.2 minutes ago.

limitación

updateIntervalInSeconds no puede habilitarse para unit mayores que hour (por lo tanto, no para day, week, quarter, year). Principalmente porque no tiene sentido programar un timeout en days, y la cantidad de ms en un día supera el máximo que acepta setTimeout.

FormattedNumber

Este componente utiliza las APIs formatNumber e Intl.NumberFormat y tiene props que corresponden a Intl.NumberFormatOptions.

Props:

props: NumberFormatOptions &
{
value: number,
format: string,
children: (formattedNumber: string) => ReactElement,
}

Por defecto <FormattedNumber> renderizará el número formateado en un React.Fragment. Si necesitas personalizar el renderizado, puedes envolverlo con otro elemento React (recomendado) o pasar una función como hijo.

Ejemplo:

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

Ejemplo formateando valores monetarios

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

Formateando números usando unit

Actualmente esto es parte de ES2020 NumberFormat. Hemos proporcionado un polyfill aquí y los tipos de react-intl permiten pasar unidades sancionadas. Por ejemplo:

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

soporte en navegadores

Requiere Intl.NumberFormat.prototype.formatToParts que no está disponible en IE11. Usa nuestro polyfill si necesitas soportar IE11.

Este componente ofrece mayor personalización que FormattedNumber permitiendo que la función hija acceda a las partes subyacentes del número formateado. Las partes disponibles están listadas aquí.

Props:

props: NumberFormatOptions &
{
value: number,
format: string,
children: (parts: Intl.NumberFormatPart[]) => ReactElement,
}

Ejemplo:

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

FormattedPlural

Este componente usa las APIs formatPlural e Intl.PluralRules y tiene props que corresponden a Intl.PluralRulesOptions.

Props:

props: PluralFormatOptions &
{
value: any,

other: ReactElement,
zero: ReactElement,
one: ReactElement,
two: ReactElement,
few: ReactElement,
many: ReactElement,

children: (formattedPlural: ReactElement) => ReactElement,
}

Por defecto <FormattedPlural> seleccionará una categoría plural (zero, one, two, few, many, u other) y renderizará el elemento React correspondiente en un React.Fragment. Si necesitas personalizar el renderizado, puedes envolverlo con otro elemento React (recomendado) o pasar una función como hijo.

Ejemplo:

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

FormattedList

soporte del navegador

Esto requiere Intl.ListFormat que tiene soporte limitado en navegadores. Por favor, usa nuestro polyfill si planeas darles soporte.

Este componente utiliza la API formatList e Intl.ListFormat. Sus props corresponden a Intl.ListFormatOptions.

Props:

props: ListFormatOptions &
{
children: (chunksOrString: string | React.ReactElement[]) => ReactElement,
}

Ejemplo:

Cuando la localización es en:

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

FormattedListParts

soporte del navegador

Esto requiere Intl.ListFormat que tiene soporte limitado en navegadores. Por favor, usa nuestro polyfill si planeas darles soporte.

Este componente utiliza la API formatListToParts e Intl.ListFormat. Sus props corresponden a Intl.ListFormatOptions.

Props:

props: ListFormatOptions &
{
children: (chunks: Array<React.ReactElement | string>) => ReactElement,
}

Ejemplo:

Cuando la localización es 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

soporte del navegador

Esto requiere Intl.DisplayNames que tiene soporte limitado en navegadores. Por favor, usa nuestro polyfill si planeas darles soporte.

Este componente utiliza formatDisplayName e Intl.DisplayNames y tiene props que corresponden a DisplayNameOptions. Puede que necesites un polyfill.

Props:

props: FormatDisplayNameOptions &
{
value: string | number | Record<string, unknown>,
}

Ejemplo:

Cuando la localización es en:

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

FormattedMessage

Este componente utiliza la API formatMessage y tiene props que corresponden a un Descriptor de Mensaje.

Props:

props: MessageDescriptor &
{
values: object,
tagName: string,
children: (chunks: ReactElement) => ReactElement,
}

Sintaxis de mensajes

El formateo de cadenas/mensajes es una característica primordial de React Intl que se basa en ICU Message Formatting utilizando la Sintaxis de Mensajes ICU. Esta sintaxis permite definir mensajes desde simples hasta complejos, traducirlos y luego formatearlos en tiempo de ejecución.

Mensaje simple:

Hello, {name}

Mensaje complejo:

Hello, {name}, you have {itemCount, plural,
=0 {no items}
one {# item}
other {# items}
}.

Ver: La Guía de sintaxis de mensajes.

Message Descriptor

React Intl tiene el concepto de Message Descriptor que define los mensajes predeterminados de tu aplicación. <FormattedMessage> tiene props que corresponden a un Message Descriptor. Estos descriptores son ideales para proporcionar los datos necesarios para traducir cadenas/mensajes y contienen estas propiedades:

  • id: Identificador único y estable para el mensaje

  • description: Contexto para el traductor sobre su uso en la UI

  • defaultMessage: Mensaje predeterminado (probablemente en inglés)

type MessageDescriptor = {
id?: string
defaultMessage?: string
description?: string
}
compilar descriptores de mensaje

Los paquetes babel-plugin-formatjs y @formatjs/ts-transformer pueden compilar Message Descriptors definidos en archivos JavaScript a AST para mejor rendimiento.

Fallbacks de formateo de mensajes

Las API de formateo de mensajes realizan un esfuerzo adicional para proporcionar alternativas en situaciones comunes donde falla el formateo; como mínimo, siempre debe devolverse una cadena no vacía. Este es el algoritmo de respaldo para el formateo de mensajes:

  1. Buscar y formatear el mensaje traducido en id, pasado a <IntlProvider>.

  2. Recurrir al formateo del defaultMessage.

  3. Recurrir al mensaje traducido en el origen de id.

  4. Recurrir al origen de defaultMessage.

  5. Recurrir al id literal del mensaje.

Uso

Por defecto, <FormattedMessage> renderiza la cadena formateada en un <React.Fragment>. Si necesitas personalizar el renderizado, puedes envolverlo con otro elemento React (recomendado), especificar un tagName diferente (ej. 'div'), o pasar una función como hijo.

Ejemplo:

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

Ejemplo: función como hijo

Live Editor
<FormattedMessage id="title">{txt => <h1>{txt}</h1>}</FormattedMessage>
Result
mensaje simple

Los mensajes pueden ser cadenas simples sin marcadores de posición, siendo el tipo más común. Este caso está altamente optimizado, pero mantiene los beneficios del procedimiento de respaldo.

Formateo de Texto Enriquecido

<FormattedMessage> también admite formateo de texto enriquecido especificando una etiqueta XML en el mensaje y resolviendo esa etiqueta en la propiedad values. Aquí un ejemplo:

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

Al permitir incrustar etiquetas XML, aseguramos que no se pierda información contextual al aplicar estilos a parte de la cadena. En un ejemplo más complejo como:

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

Función como hijo

Dado que el formateo de texto enriquecido permite incrustar ReactElement, cuando se usa una función como hijo, esta recibirá los fragmentos del mensaje formateado como un único parámetro.

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

Todo el texto enriquecido se traduce conjuntamente, produciendo resultados de mayor calidad. Esto iguala funcionalidades con otras librerías de traducción como fluent de Mozilla (usando el concepto de overlays).

Extender esto también permite utilizar potencialmente otros formatos de texto enriquecido, como Markdown.