Обработка событий

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


События компонентов

Компоненты Radix UI реализуют события через стандартные свойства React, такие как onClick, onChange, onKeyDown и другие. Однако библиотека добавляет специфические хуки и пропсы для управления внутренними состояниями:

  • onOpenChange — используется для компонентов, которые имеют открытое или закрытое состояние, например Dialog, Popover, DropdownMenu. Срабатывает при изменении состояния компонента.
  • onValueChange — актуально для компонентов, работающих с выбором значений, таких как RadioGroup, ToggleGroup, Slider. Срабатывает при изменении выбранного значения.
  • onInteractOutside — позволяет реагировать на клики или фокус вне компонента. Часто применяется в модальных окнах и всплывающих меню.

Пример использования Dialog с обработкой событий открытия и закрытия:

import * as Dialog from '@radix-ui/react-dialog';
import { useState } from 'react';

function MyDialog() {
  const [open, setOpen] = useState(false);

  return (
    <Dialog.Root open={open} onOpenCha nge={setOpen}>
      <Dialog.Trigger>Открыть диалог</Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Title>Заголовок</Dialog.Title>
        <Dialog.Description>Описание диалога</Dialog.Description>
        <button onCl ick={() => setOpen(false)}>Закрыть</button>
      </Dialog.Content>
    </Dialog.Root>
  );
}

Здесь onOpenChange автоматически синхронизирует состояние диалога с переменной open. Это позволяет полностью контролировать открытие и закрытие диалога снаружи компонента.


Работа с пользовательскими событиями

Radix UI поддерживает создание собственных событий через комбинацию внутренних пропсов и обычных React-обработчиков. Например, для компонента Slider можно отслеживать не только изменение значения, но и момент начала или конца перетаскивания:

import * as Slider from '@radix-ui/react-slider';

function MySlider() {
  return (
    <Slider.Root
      defaultValue={[50]}
      max={100}
      step={1}
      onValueCha nge={(value) => console.log('Текущее значение:', value)}
      onValueCom mit={(value) => console.log('Изменение подтверждено:', value)}
    >
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb />
    </Slider.Root>
  );
}
  • onValueChange вызывается при каждом движении ползунка.
  • onValueCommit срабатывает после завершения перетаскивания, что полезно для экономии ресурсов при обработке больших объёмов данных.

Управление событиями клавиатуры

Radix UI обеспечивает доступность компонентов через обработку событий клавиатуры. Многие элементы имеют встроенные реакции на стрелки, Enter и Escape, но при необходимости можно расширить функциональность:

<Dialog.Content
  onKeyD own={(event) => {
    if (event.key === 'Escape') {
      console.log('Диалог закрыт клавишей Escape');
    }
  }}
>
  ...
</Dialog.Content>

Ключевые моменты:

  • События клавиатуры помогают соблюсти доступность интерфейса.
  • Можно комбинировать встроенные обработчики Radix UI с кастомными обработчиками React.

Отслеживание взаимодействия вне компонента

onInteractOutside позволяет отслеживать клики или фокус вне компонента, что особенно важно для выпадающих меню, тултипов и диалогов:

<Popover.Content onInteractOuts ide={() => console.log('Клик вне поповера')}>
  ...
</Popover.Content>

Особенности работы:

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

События в групповых компонентах

Компоненты вроде CheckboxGroup, ToggleGroup и RadioGroup предоставляют агрегированные события, что упрощает управление несколькими элементами:

<RadioGroup.Root value={selected} onValueCha nge={setSelected}>
  <RadioGroup.Item value="option1">Опция 1</RadioGroup.Item>
  <RadioGroup.Item value="option2">Опция 2</RadioGroup.Item>
</RadioGroup.Root>
  • onValueChange срабатывает при выборе любого элемента внутри группы.
  • Облегчает синхронизацию состояния группы с внешним состоянием React.

Ловушки и рекомендации

  1. Не следует полагаться только на стандартные события React для компонентов с собственным управлением состоянием, таких как Accordion или DropdownMenu. Использование пропсов типа onOpenChange обеспечивает корректную синхронизацию состояния.
  2. Для компонентов с динамическим рендерингом дочерних элементов важно учитывать, что события могут не сработать, если элемент ещё не отрендерен.
  3. Использование onInteractOutside совместно с onOpenChange позволяет избежать конфликтов при закрытии модальных окон или поповеров.

Обработка событий в Radix UI сочетает стандартные возможности React с расширенными механизмами контроля состояния и доступности, что позволяет строить интерактивные интерфейсы с высокой степенью гибкости и надежности.