Radix UI предоставляет низкоуровневые, полностью контролируемые компоненты пользовательского интерфейса, которые можно интегрировать в любые React-приложения. Основной принцип программного управления заключается в том, что состояние компонентов можно контролировать извне с помощью пропсов и колбеков, что обеспечивает гибкость и предсказуемость поведения интерфейса.
Неконтролируемые компоненты управляют своим
внутренним состоянием самостоятельно. Например, Accordion
или Dialog могут открываться и закрываться по внутренней
логике, без вмешательства извне:
<Dialog>
<DialogTrigger>Открыть диалог</DialogTrigger>
<DialogContent>Содержимое диалога</DialogContent>
</Dialog>
Контролируемые компоненты позволяют управлять
состоянием извне через пропсы, обычно это open,
value или checked, а также через обработчики
событий onOpenChange, onValueChange и т.д. Это
особенно важно при интеграции компонентов с глобальным состоянием,
формами или логикой бизнес-процессов.
Пример контролируемого диалога:
const [isOpen, setIsOpen] = React.useState(false);
<Dialog open={isOpen} onOpenCha nge={setIsOpen}>
<DialogTrigger>Открыть диалог</DialogTrigger>
<DialogContent>Содержимое диалога</DialogContent>
</Dialog>
Здесь isOpen полностью контролирует видимость диалога, а
setIsOpen синхронизирует состояние с внешней логикой.
Radix UI компоненты поддерживают композицию
состояния через пропсы value,
defaultValue и соответствующие колбеки. Например,
Tabs можно сделать полностью управляемыми:
const [activeTab, setActiveTab] = React.useState('tab1');
<Tabs value={activeTab} onValueCha nge={setActiveTab}>
<TabsList>
<TabsTrigger value="tab1">Вкладка 1</TabsTrigger>
<TabsTrigger value="tab2">Вкладка 2</TabsTrigger>
</TabsList>
<TabsContent value="tab1">Контент вкладки 1</TabsContent>
<TabsContent value="tab2">Контент вкладки 2</TabsContent>
</Tabs>
Такое программное управление позволяет синхронизировать состояние вкладок с URL, глобальным стором (Redux, Zustand, Recoil) или другими компонентами интерфейса.
Radix UI предоставляет рефы к DOM-элементам и иногда
expose-методы через ref или imperativeHandle,
что позволяет выполнять действия программно, не завися от
пользовательских событий.
Пример программного открытия диалога через реф:
const dialogRef = React.useRef(null);
<Dialog ref={dialogRef}>
<DialogTrigger>Открыть диалог</DialogTrigger>
<DialogContent>Содержимое</DialogContent>
</Dialog>
<button onCl ick={() => dialogRef.current?.show()}>Открыть программно</button>
Не все компоненты поддерживают прямой доступ к методам через реф, но большинство предоставляет необходимые колбеки для полного контроля состояния.
Компоненты Radix UI отлично интегрируются с React Hook Form и другими библиотеками для управления формами. Для этого используется программное управление значениями и событиями:
const { control } = useForm();
<Controller
control={control}
name="switchValue"
render={({ field }) => (
<Switch
checked={field.value}
onCheckedCha nge={field.onChange}
/>
)}
/>
Здесь Switch становится полностью управляемым, а его
состояние синхронизировано с формой.
Программное управление позволяет синхронизировать несколько
компонентов между собой. Например, один Slider
может управлять значением Progress:
const [value, setValue] = React.useState(50);
<Slider value={value} onValueCha nge={setValue} />
<Progress value={value} />
Изменение слайдера мгновенно обновляет прогресс-бар, без использования сторонних библиотек для связывания состояния.
Для больших приложений важно избегать лишних
рендеров при программном управлении. Использование
React.useCallback и мемоизация значений помогает снизить
нагрузку:
const handleChange = React.useCallback((val) => {
setValue(val);
}, []);
<Slider value={value} onValueCha nge={handleChange} />
Radix UI часто предоставляет анимированные
компоненты, например Accordion или
Collapsible. Управление открытием/закрытием программно
позволяет синхронизировать анимацию с другими событиями приложения:
const [isOpen, setIsOpen] = React.useState(false);
<Collapsible open={isOpen} onOpenCha nge={setIsOpen}>
<CollapsibleTrigger>Toggle</CollapsibleTrigger>
<CollapsibleContent>Контент</CollapsibleContent>
</Collapsible>
<button onCl ick={() => setIsOpen((prev) => !prev)}>Программный toggle</button>
В этом примере анимация раскрытия полностью подчинена внешнему состоянию.
Программное управление в Radix UI открывает возможности гибкого интегрирования компонентов в сложные React-приложения, синхронизации с глобальным состоянием, формами и внешней логикой, при этом сохраняя полный контроль над поведением интерфейса и минимизируя непредсказуемые побочные эффекты.