Radix UI предоставляет высоко настраиваемые, доступные компоненты
пользовательского интерфейса, которые можно использовать внутри форм
React. Ключевой аспект работы с формами — управление состоянием,
валидацией и взаимодействием компонентов с библиотеками управления
формами, такими как react-hook-form или
formik.
Radix UI сам по себе не включает внутренние механизмы управления формами, поэтому важно понимать, как синхронизировать его контролируемые и неконтролируемые компоненты с форм-менеджером.
Radix UI компонентов внутри формКонтролируемый компонент получает значение через value и
уведомляет о изменениях через onChange. Пример на базе
Switch:
import * as React from "react";
import * as Switch from "@radix-ui/react-switch";
function ControlledSwitch({ value, onChange }) {
return (
<Switch.Root
checked={value}
onCheckedCha nge={onChange}
className="switch-root"
>
<Switch.Thumb className="switch-thumb" />
</Switch.Root>
);
}
Для интеграции с react-hook-form используется метод
Controller, который связывает Radix UI с системой
управления формой:
import { useForm, Controller } from "react-hook-form";
function FormExample() {
const { handleSubmit, control } = useForm({
defaultValues: { newsletter: false }
});
const onSub mit = (data) => console.log(data);
return (
<form onSub mit={handleSubmit(onSubmit)}>
<Controller
name="newsletter"
control={control}
render={({ field }) => (
<ControlledSwitch value={field.value} onCha nge={field.onChange} />
)}
/>
<button type="submit">Отправить</button>
</form>
);
}
Ключевой момент: все свойства Radix UI должны быть синхронизированы с
field.value и field.onChange для корректного
отражения состояния формы.
Неконтролируемые компоненты используют внутреннее состояние и уведомляют об изменениях через колбэки. Для таких компонентов важно использовать их API событий:
<Switch.Root
defaultChecked
onCheckedCha nge={(checked) => console.log("Checked:", checked)}
>
<Switch.Thumb />
</Switch.Root>
При интеграции с формой можно отслеживать эти события и обновлять состояние формы вручную.
react-hook-form и FormikRadix UI хорошо сочетается с react-hook-form благодаря
удобному контролю состояния через Controller. Важные
моменты:
Controller — обязательный для
контролируемых компонентов, которые не используют стандартные HTML
input.defaultValue — должно соответствовать
типу компонента (boolean для Switch, строка для Input и т.
д.).react-hook-form
указывается через rules в Controller, что
позволяет централизованно управлять ошибками.Для Formik интеграция схожа: компонент получает
value и onChange из
formik.getFieldProps или напрямую через
setFieldValue.
import { useFormik } from "formik";
import * as Checkbox from "@radix-ui/react-checkbox";
function FormikForm() {
const formik = useFormik({
initialValues: { agree: false },
onSubmit: (values) => console.log(values)
});
return (
<form onSub mit={formik.handleSubmit}>
<Checkbox.Root
checked={formik.values.agree}
onCheckedCha nge={(value) => formik.setFieldValue("agree", value)}
>
<Checkbox.Indicator />
</Checkbox.Root>
<button type="submit">Отправить</button>
</form>
);
}
Radix UI предоставляет низкоуровневые визуальные компоненты, но не управляет ошибками. Их отображение нужно реализовать вручную:
{errors.agree && (
<span className="error-message">{errors.agree.message}</span>
)}
Важно отделять логику формы от визуального состояния компонентов Radix UI: компоненты отвечают за доступность и визуальный контроль, форма — за данные и ошибки.
Комбинация различных компонентов Radix UI в одной форме:
import * as Checkbox from "@radix-ui/react-checkbox";
import * as Switch from "@radix-ui/react-switch";
import * as RadioGroup from "@radix-ui/react-radio-group";
import { useForm, Controller } from "react-hook-form";
function ComplexForm() {
const { control, handleSubmit } = useForm({
defaultValues: { agree: false, newsletter: true, gender: "male" }
});
const onSub mit = (data) => console.log(data);
return (
<form onSub mit={handleSubmit(onSubmit)}>
<Controller
name="agree"
control={control}
render={({ field }) => (
<Checkbox.Root checked={field.value} onCheckedCha nge={field.onChange}>
<Checkbox.Indicator />
</Checkbox.Root>
)}
/>
<Controller
name="newsletter"
control={control}
render={({ field }) => (
<Switch.Root checked={field.value} onCheckedCha nge={field.onChange}>
<Switch.Thumb />
</Switch.Root>
)}
/>
<Controller
name="gender"
control={control}
render={({ field }) => (
<RadioGroup.Root value={field.value} onValueCha nge={field.onChange}>
<RadioGroup.Item value="male" />
<RadioGroup.Item value="female" />
</RadioGroup.Root>
)}
/>
<button type="submit">Отправить</button>
</form>
);
}
Здесь показано, как использовать несколько типов компонентов Radix UI одновременно, сохраняя полное управление состоянием формы.
Controller для всех неклассических HTML
элементов.aria атрибуты, focus
management), которую Radix UI обеспечивает по умолчанию.boolean, string,
number).Radix UI позволяет создавать формы с современным интерфейсом, доступные и полностью управляемые, если правильно связать его с системой управления формой.