Radix UI предоставляет низкоуровневые, полностью управляемые компоненты пользовательского интерфейса для React, которые можно использовать для построения сложных интерфейсов без ограничения дизайна. Одним из ключевых аспектов взаимодействия с формами является интеграция этих компонентов с валидационными библиотеками, такими как React Hook Form, Formik, Yup или Zod.
Radix UI ориентирован на контроль состояния через пропсы и слоты. Это означает, что для корректной интеграции с валидационными библиотеками необходимо:
value и
onChange.Пример типового подхода:
import { useForm } from "react-hook-form";
import * as RadixInput from "@radix-ui/react-input";
function FormExample() {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSub mit = (data) => console.log(data);
return (
<form onSub mit={handleSubmit(onSubmit)}>
<RadixInput.Root>
<RadixInput.Input
{...register("username", { required: "Поле обязательно" })}
placeholder="Введите имя"
/>
{errors.username && <span>{errors.username.message}</span>}
</RadixInput.Root>
<button type="submit">Отправить</button>
</form>
);
}
В этом примере RadixInput.Input
выступает контролируемым компонентом, который напрямую взаимодействует с
React Hook Form. Ошибки валидации отображаются через
условный рендеринг.
Radix UI часто используется для создания сложных элементов, таких как селекты, чекбоксы и радиокнопки. Для таких компонентов важно корректно обрабатывать событие изменения значения и синхронизировать его с библиотекой валидации.
Пример для кастомного селекта:
import * as Sel ect from "@radix-ui/react-select";
import { useForm, Controller } fr om "react-hook-form";
function CustomSelectForm() {
const { control, handleSubmit, formState: { errors } } = useForm();
const onSub mit = (data) => console.log(data);
return (
<form onSub mit={handleSubmit(onSubmit)}>
<Controller
name="fruit"
control={control}
rules={{ required: "Выберите фрукт" }}
render={({ field }) => (
<Sel ect.Root onValueCha nge={field.onChange} value={field.value}>
<Sel ect.Trigger>
<Sel ect.Value placeholder="Выберите фрукт" />
</Sel ect.Trigger>
<Sel ect.Content>
<Select.Item value="apple">Яблоко</Select.Item>
<Select.Item value="orange">Апельсин</Select.Item>
<Select.Item value="banana">Банан</Select.Item>
</Select.Content>
</Select.Root>
)}
/>
{errors.fruit && <span>{errors.fruit.message}</span>}
<button type="submit">Отправить</button>
</form>
);
}
Использование Controller из
React Hook Form позволяет обернуть сложные компоненты Radix
UI, которые не предоставляют стандартного события onChange
на уровне DOM, и корректно подключить их к валидации.
Для более сложной валидации рекомендуется использовать схемы Yup или Zod. Пример интеграции с Yup:
import { useForm } fr om "react-hook-form";
import { yupResolver } fr om "@hookform/resolvers/yup";
import * as yup fr om "yup";
import * as RadixInput fr om "@radix-ui/react-input";
const schema = yup.object({
email: yup.string().email("Неверный формат email").required("Обязательное поле"),
});
function EmailForm() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: yupResolver(schema),
});
const onSub mit = (data) => console.log(data);
return (
<form onSub mit={handleSubmit(onSubmit)}>
<RadixInput.Root>
<RadixInput.Input {...register("email")} placeholder="Введите email" />
{errors.email && <span>{errors.email.message}</span>}
</RadixInput.Root>
<button type="submit">Отправить</button>
</form>
);
}
Использование схем упрощает поддержку и расширение правил валидации, особенно когда формы содержат большое количество полей.
Radix UI предоставляет возможность создавать собственные тултипы, тулбары и индикаторы для ошибок. Важным моментом является синхронизация состояния ошибки с визуальным компонентом:
import * as Tooltip fr om "@radix-ui/react-tooltip";
<Tooltip.Root>
<Tooltip.Trigger asChild>
<RadixInput.Input {...register("password")} placeholder="Пароль" />
</Tooltip.Trigger>
{errors.password && (
<Tooltip.Content side="right">
{errors.password.message}
</Tooltip.Content>
)}
</Tooltip.Root>
Такой подход обеспечивает единый стиль отображения ошибок без
использования стандартных HTML-элементов <span> или
<div> для текста ошибки, что повышает визуальную
согласованность интерфейса.
Controller из React Hook Form.Интеграция Radix UI с валидационными библиотеками обеспечивает гибкий, полностью кастомизируемый интерфейс с мощными инструментами управления состоянием и ошибок, что особенно важно для сложных и динамических форм.