useSwitch для переключателей

useSwitch — это хук из библиотеки React Aria, предназначенный для создания доступных переключателей (switch, аналог toggle), соответствующих стандартам ARIA и поддерживающих правильную работу с клавиатурой, экранными читалками и другими ассистивными технологиями.

Хук не рендерит UI, а предоставляет необходимые пропсы и состояния, которые затем можно применить к любому компоненту переключателя.


Импорт и базовое использование

import {useSwitch} from '@react-aria/switch';
import {useToggleState} from '@react-stately/toggle';
import {useRef} from 'react';

function SwitchExample() {
  const state = useToggleState({});
  const ref = useRef();
  const {inputProps} = useSwitch({isSelected: state.isSelected, onChange: state.toggle}, ref);

  return (
    <label>
      <input {...inputProps} ref={ref} />
      Включено
    </label>
  );
}
  • useToggleState из React Stately используется для управления состоянием переключателя.
  • inputProps содержит все атрибуты и обработчики событий, необходимые для корректной работы переключателя.
  • ref требуется для привязки к DOM-элементу <input>.

Аргументы хука useSwitch

Хук принимает объект с ключевыми параметрами:

  • isSelected — булево значение, определяющее состояние переключателя.
  • defaultSelected — начальное значение при создании состояния.
  • onChange — функция обратного вызова при изменении состояния.
  • isDisabled — блокировка переключателя.
  • children — содержимое метки переключателя (label).

Пример:

const {inputProps} = useSwitch({
  isSelected: true,
  onChange: () => console.log('Переключатель изменён'),
  isDisabled: false
}, ref);

Возвращаемые значения

Хук возвращает объект с основными пропсами:

  • inputProps — пропсы для <input type="checkbox"> или <input type="switch">.
  • isSelected (опционально) — текущее состояние, если требуется внешняя проверка.
  • isDisabled — состояние доступности, может использоваться для кастомной стилизации.

Применение inputProps гарантирует:

  • Корректные ARIA-атрибуты: role="switch", aria-checked.
  • Управление фокусом и событиями клавиатуры.
  • Совместимость с экранными читалками.

Настройка кастомного UI

useSwitch позволяет использовать любой элемент для визуализации переключателя, не ограничиваясь стандартным <input>:

function CustomSwitch() {
  const state = useToggleState({});
  const ref = useRef();
  const {inputProps} = useSwitch({isSelected: state.isSelected, onChange: state.toggle}, ref);

  return (
    <div 
      role="switch" 
      aria-checked={state.isSelected} 
      tabIndex={0} 
      onCl ick={state.toggle} 
      onKeyD own={(e) => e.key === 'Enter' && state.toggle()}
      ref={ref}
      style={{
        width: '50px',
        height: '25px',
        background: state.isSelected ? 'green' : 'gray',
        borderRadius: '15px',
        cursor: 'pointer',
        position: 'relative'
      }}
    >
      <div style={{
        width: '23px',
        height: '23px',
        background: 'white',
        borderRadius: '50%',
        position: 'absolute',
        top: '1px',
        left: state.isSelected ? '26px' : '1px',
        transition: 'left 0.2s'
      }} />
    </div>
  );
}

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

  • role="switch" и aria-checked нужны для доступности.
  • Управление событиями onClick и onKeyDown обеспечивает интерактивность.
  • Состояние переключателя управляется через useToggleState или через isSelected/onChange из родительского компонента.

Работа с клавиатурой и фокусом

useSwitch автоматически добавляет обработку клавиатуры для <input>:

  • Пробел (Space) — переключает состояние.
  • Enter — также может срабатывать, если реализован на кастомном элементе.
  • Фокус управляется через стандартный tabIndex и ref.

Для кастомного UI необходимо явно обрабатывать клавиши:

<div
  role="switch"
  aria-checked={state.isSelected}
  tabIndex={0}
  onKeyD own={(e) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      state.toggle();
    }
  }}
>

Советы по доступности

  • Всегда добавляйте метку (label) или используйте aria-label/aria-labelledby.
  • Для кастомного UI используйте role="switch" и aria-checked.
  • Не отключайте tabIndex — элемент должен быть доступен через клавиатуру.
  • Обрабатывайте события onKeyDown для поддержки пробела и Enter.

Интеграция с формами

inputProps поддерживает стандартные атрибуты формы:

<input {...inputProps} name="newsletter" value="subscribe" />
  • name и value позволяют включить переключатель в <form> и отправлять данные на сервер.
  • Управление через isSelected и onChange совместимо с библиотеками управления формами.

Заключение по хуку

useSwitch обеспечивает полную ARIA-доступность, позволяет использовать кастомные элементы и легко интегрируется с состоянием через useToggleState или внешние пропсы. Это делает его идеальным инструментом для создания профессиональных переключателей в React-приложениях.