Многие компоненты интерфейса управляют выбором значений. В одних случаях допустим только один выбранный элемент, в других — несколько одновременно. Библиотека Radix UI реализует оба подхода через единый концептуальный механизм управления состоянием.
Одиночные и множественные значения применяются в различных компонентах:
AccordionToggleGroupTabsRadioGroupCheckboxSelectОсновное различие между режимами заключается в структуре состояния:
| Тип выбора | Структура значения | Поведение |
|---|---|---|
| Одиночное значение | строка (string) |
выбран только один элемент |
| Множественные значения | массив (string[]) |
выбран набор элементов |
Radix UI не скрывает состояние внутри компонента, а предоставляет гибкую систему контролируемых и неконтролируемых состояний, что позволяет управлять значениями из внешнего состояния приложения.
В режиме одиночного выбора компонент хранит одно активное
значение. Каждый элемент имеет собственный идентификатор
(value). Когда пользователь выбирает элемент, именно его
значение становится текущим состоянием.
Внутри компонентов Radix это состояние обычно представлено строкой:
"value-1"
При выборе другого элемента предыдущее значение автоматически заменяется.
Компонент Accordion может работать в режиме, где
одновременно открыт только один элемент.
import * as Accordion from "@radix-ui/react-accordion";
export default function Example() {
return (
<Accordion.Root type="single">
<Accordion.Item value="item-1">
<Accordion.Header>
<Accordion.Trigger>Раздел 1</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content>
Содержимое первого раздела
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-2">
<Accordion.Header>
<Accordion.Trigger>Раздел 2</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content>
Содержимое второго раздела
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
);
}
Ключевой параметр:
type="single"
Этот режим обеспечивает следующие свойства:
Radix UI позволяет полностью контролировать выбранное значение через React-состояние.
const [value, setValue] = React.useState("item-1");
<Accordion.Root
type="single"
value={value}
onValueCha nge={setValue}
>
Поведение:
value — текущее активное значениеonValueChange — обработчик измененияЭто особенно важно в сложных интерфейсах, где выбор должен:
В одиночном режиме по умолчанию всегда выбран один элемент. Однако поведение можно изменить.
Параметр:
collapsible
Пример:
<Accordion.Root type="single" collapsible>
Теперь возможно:
В таком случае значение становится:
undefined
В режиме множественного выбора пользователь может активировать несколько элементов одновременно. Состояние компонента представлено массивом значений.
Пример состояния:
["item-1", "item-3", "item-5"]
Каждый элемент независимо добавляется или удаляется из массива.
<Accordion.Root type="multiple">
<Accordion.Item value="item-1">
<Accordion.Header>
<Accordion.Trigger>Раздел 1</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content>
Контент
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-2">
<Accordion.Header>
<Accordion.Trigger>Раздел 2</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content>
Контент
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
Особенности:
Контролируемый режим выглядит следующим образом:
const [values, setValues] = React.useState(["item-1"]);
<Accordion.Root
type="multiple"
value={values}
onValueCha nge={setValues}
/>
Тип состояния:
string[]
Пример изменения массива:
["item-1"] → ["item-1", "item-2"]
["item-1", "item-2"] → ["item-2"]
Radix автоматически управляет добавлением и удалением значений.
Компонент ToggleGroup демонстрирует особенно наглядную
разницу между режимами.
import * as ToggleGroup from "@radix-ui/react-toggle-group";
<ToggleGroup.Root type="single">
<ToggleGroup.Item value="bold">B</ToggleGroup.Item>
<ToggleGroup.Item value="italic">I</ToggleGroup.Item>
<ToggleGroup.Item value="underline">U</ToggleGroup.Item>
</ToggleGroup.Root>
Поведение:
Такой режим напоминает RadioGroup.
<ToggleGroup.Root type="multiple">
<ToggleGroup.Item value="bold">B</ToggleGroup.Item>
<ToggleGroup.Item value="italic">I</ToggleGroup.Item>
<ToggleGroup.Item value="underline">U</ToggleGroup.Item>
</ToggleGroup.Root>
Поведение:
Этот режим напоминает набор чекбоксов.
Radix придерживается строгой типизации значений.
Тип значения:
string | undefined
Пример:
"tab-1"
или
undefined
если элемент закрыт.
Тип значения:
string[]
Пример:
["bold", "italic"]
или
[]
если ничего не выбрано.
Radix использует два способа задания состояния.
Используется для неконтролируемых компонентов.
<Accordion.Root
type="single"
defaultValue="item-1"
/>
Или для множественного режима:
<Accordion.Root
type="multiple"
defaultValue={["item-1", "item-2"]}
/>
После инициализации состояние управляется внутри компонента.
Используется для контролируемых компонентов.
<Accordion.Root
type="single"
value={value}
onValueCha nge={setValue}
/>
Или:
<Accordion.Root
type="multiple"
value={values}
onValueCha nge={setValues}
/>
В этом случае Radix выступает только как UI-слой, а логика состояния находится в приложении.
Radix реализует стандартные операции над состоянием.
Алгоритм:
1. пользователь выбирает элемент
2. значение становится равным value элемента
3. предыдущий элемент деактивируется
Если включен collapsible:
4. повторный клик очищает значение
Алгоритм:
1. пользователь нажимает элемент
2. если значение отсутствует — оно добавляется в массив
3. если значение уже есть — оно удаляется
Это можно представить как операцию:
toggle(value)
Используются в ситуациях, где необходимо выбрать ровно один вариант.
Примеры интерфейсов:
Компоненты Radix:
TabsRadioGroupSelectAccordion (single)ToggleGroup (single)Используются в интерфейсах, где допускается комбинация опций.
Примеры:
Компоненты Radix:
CheckboxToggleGroup (multiple)Accordion (multiple)Множественные значения особенно важны в динамических интерфейсах.
Пример фильтрации:
["size-large", "color-red", "brand-nike"]
Каждый параметр можно включать и отключать независимо.
В React это часто реализуется через useState:
const [filters, setFilters] = useState([]);
Radix автоматически синхронизирует UI с этим состоянием.
Ошибка:
type="multiple"
value="item-1"
Правильный вариант:
value={["item-1"]}
Некорректно:
<Accordion.Root
value={value}
defaultValue="item-1"
/>
Компонент должен быть либо:
Если используется value, необходимо передать
обработчик:
onValueCha nge={setValue}
Иначе состояние будет заблокировано.
Подход Radix к одиночным и множественным значениям формирует унифицированную модель управления состоянием:
valueonValueChangeЭта архитектура позволяет: