Cómo formatear números para diferentes configuraciones regionales en TanStack Start v1

Mostrar números con separadores específicos según la configuración regional

Problema

Los números se escriben de manera diferente en todo el mundo. Lo que aparece como 10,000.5 en Estados Unidos se convierte en 10.000,5 en Alemania—las comas y los puntos intercambian roles por completo. Esto no es una cuestión de preferencia o estilo, sino de legibilidad. Un usuario alemán que ve 10,000.5 podría leerlo como diez, ignorando los separadores de agrupación. Un usuario estadounidense que ve 10.000,5 podría leerlo como diez mil, ignorando el separador decimal. Los mismos dígitos, significados opuestos.

Cuando las aplicaciones muestran números sin considerar las convenciones de formato regionales, crean confusión y erosionan la confianza. Los usuarios esperan que los números sigan los patrones que aprendieron, y las desviaciones de esos patrones los obligan a detenerse, reinterpretar y cuestionar si los datos son correctos.

Solución

Formatear números basados en la configuración regional del usuario, utilizando reglas regionales para separadores decimales y de agrupación. Esto convierte los valores numéricos en cadenas que siguen las reglas de formato familiares para los usuarios en su región.

React-intl proporciona componentes y hooks que aprovechan la API integrada del navegador Intl.NumberFormat para aplicar el formato específico de la configuración regional. Al pasar un valor numérico y la configuración regional actual, estas herramientas seleccionan automáticamente los separadores correctos, la agrupación de dígitos y otras convenciones regionales. El resultado es una cadena formateada que coincide con las expectativas del usuario sin manipulación manual de cadenas o lógica específica de la configuración regional en tus componentes.

Pasos

1. Crear un componente de visualización de números usando FormattedNumber

Construye un componente que acepte un valor numérico y lo renderice con formato apropiado para la configuración regional utilizando el componente FormattedNumber de react-intl.

import { FormattedNumber } from "react-intl";

interface PriceDisplayProps {
  value: number;
}

export function PriceDisplay({ value }: PriceDisplayProps) {
  return (
    <div>
      <FormattedNumber value={value} />
    </div>
  );
}

El componente FormattedNumber aplica automáticamente los separadores decimales y de agrupación de la configuración regional. Lee la configuración regional del IntlProvider más cercano en el árbol de componentes y formatea el número en consecuencia.

2. Formatear números con estilos específicos

Personaliza el formato de números pasando opciones de estilo a FormattedNumber para monedas, porcentajes o unidades.

import { FormattedNumber } from "react-intl";

interface MetricsProps {
  revenue: number;
  growthRate: number;
  fileSize: number;
}

export function Metrics({ revenue, growthRate, fileSize }: MetricsProps) {
  return (
    <div>
      <p>
        Ingresos:{" "}
        <FormattedNumber value={revenue} style="currency" currency="USD" />
      </p>
      <p>
        Crecimiento: <FormattedNumber value={growthRate} style="percent" />
      </p>
      <p>
        Tamaño:{" "}
        <FormattedNumber
          value={fileSize}
          style="unit"
          unit="megabyte"
          unitDisplay="short"
        />
      </p>
    </div>
  );
}

La propiedad style controla el modo de formato. El formato de moneda requiere un código currency, el formato de porcentaje multiplica automáticamente por 100, y el formato de unidad requiere un identificador unit. Todos los estilos respetan las convenciones del idioma activo.

3. Formatear números imperativamente con useIntl

Utiliza el hook useIntl para formatear números en contextos donde los componentes no son adecuados, como generar atributos dinámicos o preparar datos para APIs que no son de React.

import { useIntl } from "react-intl";

interface ChartTooltipProps {
  dataPoint: number;
}

export function ChartTooltip({ dataPoint }: ChartTooltipProps) {
  const intl = useIntl();
  const formattedValue = intl.formatNumber(dataPoint, {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  });

  return <div title={formattedValue}>{formattedValue}</div>;
}

El método formatNumber devuelve inmediatamente una cadena formateada, lo que lo hace adecuado para atributos, etiquetas aria, o cualquier contexto donde necesites el valor formateado como una cadena en lugar de un elemento React.

4. Aplicar opciones de formato personalizadas

Controla la precisión, agrupación y notación pasando Intl.NumberFormatOptions a FormattedNumber o formatNumber.

import { FormattedNumber } from "react-intl";

interface StatisticProps {
  value: number;
  compact?: boolean;
}

export function Statistic({ value, compact }: StatisticProps) {
  return (
    <div>
      <FormattedNumber
        value={value}
        notation={compact ? "compact" : "standard"}
        minimumFractionDigits={0}
        maximumFractionDigits={2}
      />
    </div>
  );
}

Opciones como notation, minimumFractionDigits y maximumFractionDigits controlan cómo se muestra el número. La notación compacta convierte números grandes a formas abreviadas como "1.2M" respetando las abreviaturas específicas del idioma.