Componentes
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.
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:
<FormattedDate value={new Date(1459832991883)} />
Ejemplo con opciones:
<FormattedDate value={new Date(1459832991883)} year="numeric" month="long" day="2-digit" />
FormattedDateParts
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,
}
<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>
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:
<FormattedTime value={new Date(1459832991883)} />
FormattedTimeParts
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,
}
<FormattedTimeParts value={new Date(1459832991883)}> {parts => ( <> <b>{parts[0].value}</b> {parts[1].value} <small>{parts[2].value}</small> </> )} </FormattedTimeParts>
FormattedDateTimeRange
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:
<FormattedDateTimeRange from={new Date('2020-1-1')} to={new Date('2020-1-15')} />
FormattedRelativeTime
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:
<FormattedRelativeTime value={0} numeric="auto" updateIntervalInSeconds={1} />
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:
<FormattedRelativeTime value={-50} updateIntervalInSeconds={1} />
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.
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:
<FormattedNumber value={1000} />
Ejemplo formateando valores monetarios
<FormattedNumber value={1000} style="currency" currency="USD" />
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:
<FormattedNumber value={1000} style="unit" unit="kilobyte" unitDisplay="narrow" />
<FormattedNumber value={1000} unit="fahrenheit" unitDisplay="long" style="unit" />
FormattedNumberParts
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:
<FormattedNumberParts value={1000}> {parts => ( <> <b>{parts[0].value}</b> {parts[1].value} <small>{parts[2].value}</small> </> )} </FormattedNumberParts>
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:
<FormattedPlural value={10} one="message" other="messages" />
FormattedList
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:
<FormattedList type="conjunction" value={['Me', 'myself', 'I']} />
<FormattedList type="conjunction" value={['Me', <b>myself</b>, 'I']} />
FormattedListParts
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:
<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>
FormattedDisplayName
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:
<FormattedDisplayName type="language" value="zh-Hans-SG" />
<FormattedDisplayName type="currency" value="JPY" />
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
}
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:
-
Buscar y formatear el mensaje traducido en
id, pasado a<IntlProvider>. -
Recurrir al formateo del
defaultMessage. -
Recurrir al mensaje traducido en el origen de
id. -
Recurrir al origen de
defaultMessage. -
Recurrir al
idliteral 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:
<FormattedMessage id="app.greeting" description="Greeting to welcome the user to the app" defaultMessage="Hello, {name}!" values={{ name: 'Eric', }} />
Ejemplo: función como hijo
<FormattedMessage id="title">{txt => <h1>{txt}</h1>}</FormattedMessage>
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:
<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 />, }} />
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:
<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>, }} />
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.
<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>
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.