useCheckboxGroup для групп

useCheckboxGroup — это хук из библиотеки React Aria, предназначенный для управления группами чекбоксов с поддержкой доступности (accessibility) и корректного взаимодействия с пользователем. Он обеспечивает правильное поведение для скринридеров, клавиатурной навигации и управляет состоянием группы.

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


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

import { useCheckboxGroup } from '@react-aria/checkbox';
import { useCheckbox } from '@react-aria/checkbox';
import { useState } from 'react';

function CheckboxGroupExample() {
  const [selectedValues, setSelectedValues] = useState([]);

  const { groupProps, labelProps } = useCheckboxGroup({
    label: 'Выберите любимые фрукты',
    value: selectedValues,
    onChange: setSelectedValues
  });

  return (
    <div {...groupProps}>
      <label {...labelProps}>Выберите любимые фрукты</label>
      <Checkbox value="apple" label="Яблоко" selectedValues={selectedValues} onCha nge={setSelectedValues} />
      <Checkbox value="orange" label="Апельсин" selectedValues={selectedValues} onCha nge={setSelectedValues} />
      <Checkbox value="banana" label="Банан" selectedValues={selectedValues} onCha nge={setSelectedValues} />
    </div>
  );
}

function Checkbox({ value, label, selectedValues, onChange }) {
  const { inputProps } = useCheckbox({ value, isSelected: selectedValues.includes(value), onChange });
  
  return (
    <label>
      <input {...inputProps} />
      {label}
    </label>
  );
}

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

  • groupProps — содержит свойства для контейнера группы, включая роль group и атрибуты доступности.
  • labelProps — связывает текстовую метку с группой чекбоксов.
  • value и onChange передаются для контроля состояния группы.

Параметры useCheckboxGroup

  1. label Строка с текстом для описания группы. Используется для скринридеров.

  2. value Массив выбранных значений. Каждый элемент соответствует value отдельного чекбокса.

  3. onChange Функция, вызываемая при изменении состояния группы. Получает новый массив выбранных значений.

  4. isDisabled Опционально. Блокирует все чекбоксы в группе.

  5. name Имя для группы, которое будет использоваться в input-элементах.


Управление состоянием

useCheckboxGroup не управляет состоянием автоматически — оно должно храниться в React состоянии (useState или useReducer). Хук возвращает свойства для контейнера и метки, а также поддерживает передачу функции onChange для синхронизации состояния.

Пример синхронизации состояния:

const [selected, setSelected] = useState(['apple']);

function handleChange(newValues) {
  setSelected(newValues);
}

Каждое изменение чекбокса автоматически формирует новый массив выбранных значений и передаёт его через onChange.


Доступность (Accessibility)

React Aria гарантирует, что:

  • Контейнер группы имеет роль group или fieldset.

  • Метка группы (labelProps) связана с контейнером через aria-labelledby.

  • Каждый чекбокс получает правильные атрибуты:

    • aria-checked — текущее состояние.
    • aria-disabled — если чекбокс заблокирован.
    • name — чтобы скринридеры корректно воспринимали группу как один логический элемент.

Клавиатурная навигация полностью поддерживается:

  • Tab для перехода к группе.
  • Стрелки и пробел для выбора/снятия галочки внутри группы.

Пример сложной группы с управлением

const fruits = ['apple', 'orange', 'banana', 'grape', 'kiwi'];

function AdvancedCheckboxGroup() {
  const [selectedFruits, setSelectedFruits] = useState([]);

  const { groupProps, labelProps } = useCheckboxGroup({
    label: 'Выберите фрукты',
    value: selectedFruits,
    onChange: setSelectedFruits
  });

  return (
    <fieldset {...groupProps}>
      <legend {...labelProps}>Выберите фрукты</legend>
      {fruits.map(fruit => (
        <Checkbox
          key={fruit}
          value={fruit}
          label={fruit.charAt(0).toUpperCase() + fruit.slice(1)}
          selectedValues={selectedFruits}
          onCha nge={setSelectedFruits}
        />
      ))}
    </fieldset>
  );
}

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

  • Использование fieldset и legend для групп с семантической разметкой.
  • Динамическое создание чекбоксов из массива.
  • Состояние хранится централизованно и легко расширяется.

Интеграция с кастомными компонентами

useCheckboxGroup и useCheckbox можно использовать с любым визуальным компонентом, не ограничиваясь стандартным <input type="checkbox">. Важно правильно передать inputProps к корневому элементу, чтобы сохранить доступность.

function CustomCheckbox({ value, label, selectedValues, onChange }) {
  const { inputProps } = useCheckbox({ value, isSelected: selectedValues.includes(value), onChange });

  return (
    <div role="checkbox" {...inputProps} tabIndex={0}>
      <span>{selectedValues.includes(value) ? '[x]' : '[ ]'}</span> {label}
    </div>
  );
}
  • role="checkbox" и tabIndex={0} делают кастомный элемент доступным.
  • inputProps передает обработчики событий и атрибуты aria-checked, aria-disabled.

Рекомендации по использованию

  • Всегда использовать labelProps и groupProps для доступности.
  • Хранить выбранные значения в одном состоянии и передавать через value/onChange.
  • Для больших групп предпочтительно использовать динамическую генерацию чекбоксов.
  • Кастомные компоненты должны принимать и правильно применять inputProps.

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