Volver

Cómo manejar los plurales en React

Archie McKenzie avatarArchie McKenzie
guidepluralsinternationalizationreactnextjsi18nintl

Por qué importa la pluralización en React

A menudo nos encontramos con aplicaciones que muestran mensajes poco naturales como:

Tienes 1 nuevo(s) mensaje(s)

Esta es una señal inequívoca de un desarrollador que no ha pensado detenidamente en la experiencia de usuario.

Las aplicaciones React a menudo necesitan manejar la pluralización: para recuentos de notificaciones, tamaños de listas o resultados de búsqueda. Y no es tan difícil resolver bien la pluralización, especialmente si tu aplicación solo necesita estar en inglés. Pero hay muchas malas prácticas en las que suelen caer los desarrolladores principiantes, especialmente al crear interfaces multilingües.

Esta guía explica cómo manejar correctamente los plurales en inglés, formatear números para diferentes locales y crear un sistema de pluralización totalmente multilingüe en React y Next.js.

El problema de los plurales codificados manualmente

Muchos proyectos —incluidos algunos sorprendentemente grandes e importantes— incorporan la lógica de pluralización directamente en el código.

export default function Example({ n }) {
  return (
    <p>
      Displaying {n} item{n === 1 ? '' : 's'}
    </p>
  )
}

Pero la pluralización suele ser más compleja que simplemente añadir una "s" al final de una palabra. Algunos sustantivos tienen formas plurales irregulares, como "child" y "children". A veces, otras partes de la oración también deben cambiar para concordar con el sustantivo, como "is" y "are" según la cantidad.

La tabla siguiente ilustra algunos casos comunes:

EscenarioEjemplosNotas
Cantidad de viewers"1 person is watching"
"2 people are watching"
Se requieren un sustantivo irregular ("person" → "people") y cambios en el verbo.
Eliminación de ítems"Delete this message?"
"Delete these 2 messages?"
Cambios en el demostrativo ("this" vs. "these") además de la pluralización del sustantivo.
Resultados de búsqueda"No results"
"1 result found"
"2 results found"
Redacción diferente para cero, uno y varios resultados.

Usar expresiones condicionales se vuelve rápidamente inmanejable.

Y se convierte en una pesadilla cuando necesitas lanzar tu aplicación en otros idiomas. Lo que funciona en inglés a menudo deja de funcionar por completo en idiomas como el polaco o el árabe, que tienen reglas totalmente distintas para expresar cantidades. Las empresas con las que trabajamos a menudo posponen la internacionalización por lo costoso que resulta refactorizar una interfaz de usuario codificada de esta forma.


Cómo manejar los plurales en inglés

En inglés, usar los plurales correctos en tu aplicación suele ser sencillo.

Para pluralizar sustantivos de forma sencilla, escribe una función de utilidad:

export function pluralize(
  count: number,
  singular: string,
  plural: string = singular + 's'
) {
  return `${count === 1 ? singular : plural}`;
}

Ahora hay una única función para gestionar toda la lógica de pluralización, y también funciona con plurales irregulares:

pluralize(2, 'user') // "users"
pluralize(2, 'person', 'people') // "people"
pluralize(2, 'child', 'children') // "children"

Pero ¿qué pasa si necesitas una lógica más compleja, como:

"No one is watching"
"1 person is watching"
"2 people are watching"

En este punto, deberías plantearte seriamente usar una biblioteca de internacionalización ("i18n") que requiera poco mantenimiento.

Aunque los desarrolladores suelen pensar que las bibliotecas de i18n solo sirven para interfaces multilingües, pueden ser muy útiles para la pluralización y el formato de variables incluso en aplicaciones de un solo idioma. Internamente, la mayoría de las bibliotecas de i18n usan la API integrada Intl.PluralRules de JavaScript para determinar la forma plural correcta para cualquier idioma.

Hay muchas bibliotecas de i18n para React, entre ellas la nuestra, gt-react (o gt-next si usas Next.js). Mostrar un plural en inglés con gt-react es sencillo:

import { Plural } from 'gt-react'

function Example({ count }) {
  return (
    <Plural n={count} zero={'No one is watching'} one={`${count} person is watching`}>
      {count} people are watching
    </Plural>
  )
}

La interfaz de usuario se renderiza de forma condicional en función del valor de n.

La mayoría de las bibliotecas usan la API Intl.PluralRules de JavaScript para decidir qué forma plural mostrar. Esto significa que, en inglés, usarías el nombre "one" para referirte al singular y "other" para referirte al plural. Nuestro componente <Plural> recurre a sus elementos hijo si el número proporcionado en n no coincide con ninguna de las props proporcionadas.

Usar una biblioteca aquí es una práctica recomendada incluso para aplicaciones solo en inglés, y facilita mucho la internacionalización en el futuro.


Pluralización en aplicaciones React multilingües (i18n)

Si tu aplicación solo está dirigida a usuarios que hablan inglés, puede que el enfoque anterior sea todo lo que necesites, pero la mayoría de las aplicaciones en producción acaban necesitando compatibilidad con varios idiomas. Ahí es donde las cosas se ponen interesantes.

  • En árabe, los sustantivos tienen formas diferentes según si hay cero, uno, dos o muchos
  • En español, alemán e italiano, los números grandes usan puntos en lugar de comas, así que 1,000,000 se convierte en 1.000.000
  • En hindi, los dígitos se agrupan en pares, así que 1,000,000 se convertiría en 10,00,000

Para una aplicación internacionalizada, debes usar una biblioteca de i18n específica, que tendrá su propia documentación sobre cómo manejar los plurales y el formato de número.

Formatear números para diferentes Configuraciones regionales

Puedes usar el objeto Intl para formatear números para cualquier Configuración regional. La forma más sencilla de hacerlo es con el método incorporado toLocaleString().

Por defecto, esto usará la Configuración regional actual del entorno de ejecución:

const n = 1000000
n.toLocaleString() // muestra 1,000,000 cuando la configuración regional en tiempo de ejecución es "en-US" (inglés americano)
n.toLocaleString('de') // 1.000.000 porque la configuración regional se ha especificado como "de" (alemán)

gt-react también ofrece un componente <Num> que utiliza Intl.NumberFormat internamente.

import { Num } from 'gt-react'

// muestra 1,000,000 cuando el idioma es "en-US"
// muestra 1.000.000 cuando el idioma es "de"
// muestra 10,00,000 cuando el idioma es "hi"
export default function Example() {
  return <Num>1000000</Num>
}

Comprender las formas del plural en distintos idiomas

Las seis formas de plural compatibles con la API Intl.PluralRules de JavaScript son: zero, one, two, few, many, other. Aunque el inglés usa solo one ("singular") y other ("plural"), idiomas como el árabe y el polaco tienen más de estas dos formas.

Por ejemplo, un usuario angloparlante podría esperar:

"Nadie está mirando"
"1 persona está mirando"
"2 personas están mirando"

Mientras que un usuario de habla árabe podría esperar expresiones diferentes para el singular, el dual (cuando la cantidad es exactamente de dos elementos) y las formas plurales para cantidades pequeñas y grandes:

"لا أحد يشاهد"
"1 شخص يشاهد"
"2 شخصان يشاهدان"
"3 أشخاص يشاهدون"
"11 شخصاً يشاهدون"

Aquí es donde una biblioteca de internacionalización se vuelve esencial. Cada idioma tiene su propia lógica para cuándo y cómo mostrar los plurales, así que es mejor confiar en una biblioteca específica para hacerlo bien.

Una buena biblioteca de i18n hará dos cosas:

  1. Decidir qué forma plural (one, many, other, etc.) usar según la Configuración regional
  2. Encontrar la traducción correcta en el idioma que corresponda a esa forma

Si ya tienes una biblioteca de internacionalización, comprueba su documentación para obtener información sobre el formato de plurales. Casi todas las bibliotecas tienen documentación específica sobre cómo renderizar plurales.

Ejemplo completo: plurales en una aplicación React multilingüe

Si aún no tienes una biblioteca de internacionalización, considera gt-react.

El componente <Plural> de gt-react:

  • Es una forma sencilla y declarativa de renderizar correctamente los plurales en React
  • Funciona de forma nativa con el componente de formato <Num>
  • Funciona de forma nativa con el componente de traducción <T>, que se integra con nuestro servicio de traducción gratuito para generar automáticamente las formas plurales

Juntando todas las piezas, aquí tienes un componente multilingüe completo:

import { T, Plural, Num } from 'gt-react'

// Funciona de inmediato en más de 100 idiomas
function Example({ count }) {
  return (
    <T>
      <Plural
        n={count}
        zero={'No one is watching'}
        one={
          <>
            <Num>{count}</Num> person is watching
          </>
        }
      >
        <Num>{count}</Num> people are watching
      </Plural>
    </T>
  )
}

Próximos pasos

¿Listo para manejar los plurales correctamente en tu aplicación React? Consulta nuestras guías de inicio rápido:

La pluralización es uno de los desafíos de i18n más comunes en React: hacerlo bien desde el principio te ahorrará una refactorización considerable más adelante.