Форматирование значений

React Aria предоставляет набор хуков и утилит для создания доступных интерфейсов, при этом управление форматированием значений играет ключевую роль в работе с пользовательским вводом, отображением данных и международной локализацией. Форматирование значений в React Aria строится вокруг двух основных концепций: универсальные форматы и локализованные форматы.


Локализация и международные стандарты

React Aria использует Intl API, встроенный в JavaScript, для обеспечения корректного форматирования чисел, дат, валют и процентов в зависимости от локали пользователя. Ключевые классы:

  • Intl.NumberFormat – для числовых значений и валют.
  • Intl.DateTimeFormat – для работы с датами и временем.
  • Intl.RelativeTimeFormat – для отображения относительных временных интервалов, например «2 дня назад».

Пример форматирования числа в определённой локали:

import {useLocale} from '@react-aria/i18n';

function FormattedNumber({value}) {
  let {locale} = useLocale();
  let formatted = new Intl.NumberFormat(locale).format(value);
  return <span>{formatted}</span>;
}

Здесь useLocale возвращает текущую локаль приложения, а Intl.NumberFormat корректно применяет разделители тысяч и десятичные точки согласно правилам языка.


Хуки для управления значениями

React Aria предоставляет специализированные хуки для работы с форматированными значениями в формах и интерактивных компонентах.

useNumberField

Хук для полей ввода чисел с поддержкой шагов, минимальных и максимальных значений, а также форматирования с учётом локали.

import {useNumberField} from '@react-aria/numberfield';
import {useNumberFieldState} from '@react-stately/numberfield';

function NumberInput(props) {
  let state = useNumberFieldState(props);
  let ref = React.useRef();
  let {labelProps, inputProps, incrementButtonProps, decrementButtonProps} = useNumberField(props, state, ref);

  return (
    <div>
      <label {...labelProps}>{props.label}</label>
      <div>
        <input {...inputProps} ref={ref} />
        <button {...incrementButtonProps}>+</button>
        <button {...decrementButtonProps}>-</button>
      </div>
    </div>
  );
}

Особенности:

  • Автоматическая локализованная маска ввода.
  • Контроль шагов и ограничений.
  • Поддержка клавиатурных взаимодействий для инкремента/декремента.

useDateField и useDateSegment

Для работы с датами React Aria использует сегментированное представление даты. Каждое поле (день, месяц, год) управляется отдельно, что позволяет корректно обрабатывать локализованные форматы.

import {useDateFieldState} from '@react-stately/datepicker';
import {useDateField} from '@react-aria/datepicker';

function DateInput(props) {
  let state = useDateFieldState(props);
  let ref = React.useRef();
  let {labelProps, fieldProps} = useDateField(props, state, ref);

  return (
    <div>
      <label {...labelProps}>{props.label}</label>
      <input {...fieldProps} ref={ref} />
    </div>
  );
}

Сегментированный ввод позволяет пользователю перемещаться между частями даты с клавиатуры, автоматически форматируя значения под выбранную локаль.


Форматирование валют и процентов

Использование Intl.NumberFormat с дополнительными опциями позволяет корректно обрабатывать валюты и процентные значения:

let usdFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});

let percentFormatter = new Intl.NumberFormat('ru-RU', {
  style: 'percent',
  maximumFractionDigits: 2,
});

console.log(usdFormatter.format(1234.56)); // $1,234.56
console.log(percentFormatter.format(0.1234)); // 12,34%

React Aria интегрирует такие форматтеры через состояние и хуки компонентов формы, обеспечивая единообразное отображение.


Валидация и синхронизация значений

При работе с форматированными значениями важно разделять внутреннее состояние и отображаемое значение. React Aria автоматически управляет этим через state и props:

  • state.value – внутреннее значение в типе данных JavaScript (number, Date и т.д.).
  • inputProps.value – строковое представление для отображения, локализованное и отформатированное.
  • События onChange получают внутреннее значение, что облегчает валидацию и отправку на сервер.

Пример синхронизации числа:

function handleChange(value) {
  if (value < 0) {
    alert('Значение не может быть отрицательным');
  } else {
    setNumber(value);
  }
}

Кастомизация форматов

React Aria позволяет расширять форматирование через передачу кастомных функций:

function customFormatter(value) {
  return `₽ ${value.toFixed(2).replace('.', ',')}`;
}

<input value={customFormatter(number)} onCha nge={handleChange} />

Это полезно для специфических требований, например нестандартных валют или пользовательских отображений дат.


Итоги работы с форматированием

  • Форматирование строится на основе локали и типа данных.
  • React Aria разделяет внутреннее состояние и отображаемое значение.
  • Специальные хуки (useNumberField, useDateField) управляют маской ввода, шагами и ограничениями.
  • Intl API обеспечивает правильное отображение чисел, валют, процентов и дат в любой локали.
  • Кастомные функции форматирования позволяют гибко подстраивать отображение под бизнес-требования.

Правильное использование этих инструментов обеспечивает доступный, интуитивный и корректный пользовательский интерфейс, полностью совместимый с международными стандартами и привычками пользователей.