Radix UI — это библиотека компонентов интерфейса для React, которая предоставляет низкоуровневые, полностью управляемые и доступные элементы, готовые для кастомизации. В контексте форм и ввода данных важным аспектом является серверная валидация, когда проверка данных выполняется не только на клиенте, но и на сервере для обеспечения безопасности и целостности данных.
Клиентская валидация выполняется в браузере, обычно
с использованием HTML-атрибутов (required,
pattern) или JavaScript-логики. Она обеспечивает быстрый
отклик и улучшает UX, но не гарантирует безопасность,
поскольку её можно обойти.
Серверная валидация выполняется на стороне сервера после отправки формы и является обязательной для критичных данных: аутентификация, финансовые транзакции, уникальные идентификаторы, данные пользователей.
Ключевые преимущества серверной валидации:
Radix UI предоставляет низкоуровневые компоненты, которые не включают собственную логику валидации, что позволяет интегрировать серверную проверку через обработку ошибок после submit.
@radix-ui/react-formimport * as Form from '@radix-ui/react-form';
import { useState } from 'react';
function UserForm() {
const [serverErrors, setServerErrors] = useState({});
const handleSubmit = async (event) => {
event.preventDefault();
const formData = new FormData(event.target);
const payload = Object.fromEntries(formData);
try {
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
const result = await response.json();
if (!response.ok) {
setServerErrors(result.errors);
} else {
setServerErrors({});
console.log('Данные успешно отправлены');
}
} catch (err) {
console.error('Ошибка сервера', err);
}
};
return (
<Form.Root onSub mit={handleSubmit}>
<Form.Field name="username">
<Form.Label>Имя пользователя</Form.Label>
<Form.Control asChild>
<input type="text" />
</Form.Control>
{serverErrors.username && (
<Form.Message match="valueMissing">{serverErrors.username}</Form.Message>
)}
</Form.Field>
<Form.Field name="email">
<Form.Label>Email</Form.Label>
<Form.Control asChild>
<input type="email" />
</Form.Control>
{serverErrors.email && (
<Form.Message match="typeMismatch">{serverErrors.email}</Form.Message>
)}
</Form.Field>
<Form.Submit>Отправить</Form.Submit>
</Form.Root>
);
}
В этом примере:
Form.Root управляет сабмитом
формы.Form.Field и Form.Control
связывают поле с именем и контролом.Form.Message отображает сообщения об
ошибках, включая серверные.Важно, что сообщения об ошибках сервера передаются в
компонент через serverErrors и могут быть динамически
связаны с каждым полем.
Серверная валидация часто возвращает асинхронные ошибки:
Для таких случаев используется state для ошибок и
асинхронная функция submit. Radix UI не блокирует рендер сообщений,
поэтому можно динамически обновлять Form.Message.
Пример обработки уникального имени пользователя:
if (result.errors.username === 'already_exists') {
setServerErrors((prev) => ({
...prev,
username: 'Пользователь с таким именем уже существует',
}));
}
Radix UI предоставляет доступные для экранных читалок сообщения. Важные моменты:
Form.Message с атрибутом
match, даже если сообщение приходит с сервера.aria-invalid="true").Объект ошибок по полям
Form.Message.Централизованная обработка ошибок API
Сервер возвращает структурированный JSON с массивом ошибок:
{
"errors": {
"email": "Email уже зарегистрирован",
"password": "Слишком короткий пароль"
}
}Этот объект маппится на поля формы.
Комбинация с useForm
библиотекой
react-hook-form или formik управляют логикой
валидации и серверными ошибками.С помощью Radix UI и правильной организации состояния ошибок можно создавать доступные, настраиваемые формы, которые безопасно и корректно обрабатывают серверные проверки, обеспечивая надежную валидацию данных и высокое качество UX.