Хук useDatePicker из библиотеки React Aria реализует
полноценный, доступный (accessible) интерфейс выбора даты. Он объединяет
текстовый ввод даты, кнопку открытия календаря и всплывающий календарный
интерфейс в единую систему с корректной ARIA-разметкой и поведением
клавиатуры.
Хук не рендерит готовый UI. Он предоставляет набор пропсов и состояний, которые необходимо применить к собственным React-компонентам.
useDatePicker решает несколько задач:
В основе работы лежит взаимодействие трёх библиотек:
Компонент выбора даты состоит из нескольких частей:
1. Контейнер DatePicker
Отвечает за общую структуру компонента.
2. Поле ввода даты
Разбито на сегменты:
Каждый сегмент редактируется отдельно.
3. Кнопка открытия календаря
Открывает всплывающий календарь.
4. Popover
Контейнер всплывающего окна.
5. Calendar
Календарный интерфейс выбора даты.
Для работы useDatePicker требуется несколько
пакетов:
npm install react-aria react-stately @internationalized/date
Состояние компонента управляется хуком
useDatePickerState.
import {useDatePickerState} from 'react-stately'
import {useDatePicker} from 'react-aria'
Пример создания состояния:
let state = useDatePickerState({
value: null,
onChange: setDate
})
state управляет:
Минимальная реализация DatePicker:
function DatePicker(props) {
let state = useDatePickerState(props)
let ref = React.useRef()
let {
groupProps,
fieldProps,
buttonProps,
dialogProps,
calendarProps
} = useDatePicker(props, state, ref)
return (
<div {...groupProps} ref={ref}>
<DateField {...fieldProps} />
<button {...buttonProps}>
?
</button>
{state.isOpen && (
<Popover>
<div {...dialogProps}>
<Calendar {...calendarProps} />
</div>
</Popover>
)}
</div>
)
}
useDatePicker возвращает набор пропсов:
| prop | назначение |
|---|---|
groupProps |
контейнер DatePicker |
fieldProps |
поле ввода даты |
buttonProps |
кнопка открытия календаря |
dialogProps |
контейнер popover |
calendarProps |
календарь |
DatePicker использует компонент DateField, который разбивает дату на сегменты.
Каждый сегмент редактируется отдельно.
Пример сегментов:
[ 12 ] [ 05 ] [ 2026 ]
день месяц год
Каждый сегмент:
import {useDateField} from 'react-aria'
import {useDateFieldState} from 'react-stately'
function DateField(props) {
let state = useDateFieldState(props)
let ref = React.useRef()
let {fieldProps} = useDateField(props, state, ref)
return (
<div {...fieldProps} ref={ref}>
{state.segments.map(segment => (
<DateSegment
key={segment.type}
segment={segment}
state={state}
/>
))}
</div>
)
}
Каждый сегмент управляется useDateSegment.
import {useDateSegment} from 'react-aria'
function DateSegment({segment, state}) {
let ref = React.useRef()
let {segmentProps} = useDateSegment(segment, state, ref)
return (
<span {...segmentProps} ref={ref}>
{segment.text}
</span>
)
}
Сегменты бывают следующих типов:
| тип | описание |
|---|---|
day |
день |
month |
месяц |
year |
год |
hour |
часы |
minute |
минуты |
literal |
разделители |
Для отображения календаря используется useCalendarState
и useCalendar.
import {useCalendar} from 'react-aria'
import {useCalendarState} from 'react-stately'
Пример:
function Calendar(props) {
let state = useCalendarState(props)
let ref = React.useRef()
let {calendarProps, prevButtonProps, nextButtonProps} =
useCalendar(props, state)
return (
<div {...calendarProps} ref={ref}>
<button {...prevButtonProps}>Prev</button>
<button {...nextButtonProps}>Next</button>
<CalendarGrid state={state} />
</div>
)
}
Календарь состоит из недель.
import {useCalendarGrid} from 'react-aria'
function CalendarGrid({state}) {
let {gridProps, headerProps, weekDays} =
useCalendarGrid({}, state)
return (
<table {...gridProps}>
<thead {...headerProps}>
<tr>
{weekDays.map(day => (
<th key={day}>{day}</th>
))}
</tr>
</thead>
<tbody>
{[...state.getWeeksInMonth()].map((week, i) => (
<tr key={i}>
{week.map(date => (
<CalendarCell key={date} date={date} state={state}/>
))}
</tr>
))}
</tbody>
</table>
)
}
Каждый день реализуется через useCalendarCell.
import {useCalendarCell} from 'react-aria'
function CalendarCell({state, date}) {
let ref = React.useRef()
let {
cellProps,
buttonProps,
isSelected,
isOutsideVisibleRange
} = useCalendarCell({date}, state, ref)
return (
<td {...cellProps}>
<button {...buttonProps} ref={ref}>
{date.day}
</button>
</td>
)
}
React Aria автоматически поддерживает локализацию.
Пример:
import {I18nProvider} from 'react-aria'
<I18nProvider locale="ru-RU">
<DatePicker />
</I18nProvider>
Это влияет на:
React Aria использует типы из
@internationalized/date.
Пример:
import {CalendarDate} from '@internationalized/date'
let date = new CalendarDate(2026, 3, 15)
Преимущества:
DateМожно задать допустимый диапазон дат.
<DatePicker
minValue={new CalendarDate(2020,1,1)}
maxValue={new CalendarDate(2030,12,31)}
/>
В этом случае:
<DatePicker
defaultValue={new CalendarDate(2025, 6, 10)}
/>
Отличие:
| свойство | поведение |
|---|---|
value |
контролируемый компонент |
defaultValue |
неконтролируемый |
<DatePicker
onCha nge={(date) => {
console.log(date.toString())
}}
/>
Возвращается объект:
CalendarDate
Пример:
2026-03-15
Можно контролировать popover вручную.
<DatePicker
isOpen={isOpen}
onOpenCha nge={setIsOpen}
/>
Это позволяет:
useDatePicker автоматически реализует:
groupspinbuttondialoggrid| клавиша | действие |
|---|---|
| ArrowUp | увеличить сегмент |
| ArrowDown | уменьшить |
| ArrowLeft | предыдущий сегмент |
| ArrowRight | следующий сегмент |
| Enter | открыть календарь |
| Esc | закрыть popover |
React Aria автоматически:
@internationalized/date поддерживает:
Пример:
<DatePicker
calendar="islamic"
/>
Для выбора даты и времени используется:
useDatePicker + useTimeField
Либо готовый хук:
useDateRangePicker
React Aria не включает CSS.
Стили применяются через:
Пример:
.datepicker {
display: flex;
gap: 8px;
}
.calendar {
background: white;
border: 1px solid #ccc;
}
Полноценный DatePicker состоит из:
DatePicker
├─ DateField
│ ├─ DateSegment
│ ├─ DateSegment
│ └─ DateSegment
│
├─ Button
│
└─ Popover
└─ Calendar
├─ CalendarGrid
│ └─ CalendarCell
Каждый элемент получает поведение через React Aria.
React Aria оптимизирован для:
DatePicker ререндерится только при изменении:
Наиболее распространённые применения:
Дата заезда
Дата выезда
Дата встречи
Дата дедлайна
От
До
useDatePickerОсновные параметры:
| свойство | описание |
|---|---|
value |
выбранная дата |
defaultValue |
дата по умолчанию |
onChange |
обработчик изменения |
minValue |
минимальная дата |
maxValue |
максимальная дата |
isDisabled |
блокировка |
isReadOnly |
только чтение |
isOpen |
состояние popover |
onOpenChange |
управление popover |
locale |
локализация |
useDatePickerХук применяется в случаях:
Он позволяет полностью контролировать структуру и внешний вид компонента, сохраняя стандарты доступности и поведения интерфейса.