Radix UI — это библиотека компонентов для React, ориентированная на доступность и гибкость. Взаимодействие с сервером в компонентах Radix UI обычно происходит через сторонние механизмы управления состоянием и API-запросы, однако грамотная обработка серверных ошибок напрямую влияет на пользовательский интерфейс и опыт работы с компонентами.
Компоненты Radix UI, такие как Dialog,
Toast, Popover и Form, часто
используются для отображения данных после запроса к серверу. Важным
моментом является правильное управление состоянием ошибки.
Пример паттерна обработки ошибки:
import * as Toast from '@radix-ui/react-toast';
import { useState } from 'react';
function SaveButton({ apiCall }) {
const [error, setError] = useState(null);
const handleSave = async () => {
try {
await apiCall();
setError(null);
} catch (err) {
setError(err.message || 'Произошла ошибка при сохранении');
}
};
return (
<>
<button onCl ick={handleSave}>Сохранить</button>
{error && (
<Toast.Root>
<Toast.Title>Ошибка</Toast.Title>
<Toast.Description>{error}</Toast.Description>
</Toast.Root>
)}
</>
);
}
В этом примере используется компонент Toast для
визуального уведомления о серверной ошибке. Ключевой момент — хранение
состояния ошибки в useState и динамическое отображение
уведомления только при наличии ошибки.
Radix UI предоставляет низкоуровневые компоненты для форм
(Label, Input, Field,
Form), которые можно интегрировать с серверной
валидацией.
Паттерн обработки ошибок в форме:
import { useForm } from 'react-hook-form';
import * as Form from '@radix-ui/react-form';
function ProfileForm({ saveProfile }) {
const { register, handleSubmit, setError } = useForm();
const onSub mit = async (data) => {
try {
await saveProfile(data);
} catch (err) {
if (err.fieldErrors) {
Object.entries(err.fieldErrors).forEach(([field, message]) => {
setError(field, { type: 'server', message });
});
}
}
};
return (
<Form.Root onSub mit={handleSubmit(onSubmit)}>
<Form.Field name="username">
<Form.Label>Имя пользователя</Form.Label>
<Form.Control asChild>
<input {...register('username')} />
</Form.Control>
<Form.Message match="valueMissing">Поле обязательно</Form.Message>
<Form.Message match="typeMismatch">{/* Ошибка сервера */}</Form.Message>
</Form.Field>
<button type="submit">Сохранить</button>
</Form.Root>
);
}
Здесь Radix UI Form.Message используется для отображения
как клиентских, так и серверных ошибок, что позволяет пользователю сразу
видеть, какое поле содержит некорректные данные после запроса на
сервер.
При больших приложениях полезно реализовать глобальный слой для обработки серверных ошибок. Например, с помощью контекста React:
import { createContext, useContext, useState } from 'react';
import * as Toast from '@radix-ui/react-toast';
const ErrorContext = createContext();
export const ErrorProvider = ({ children }) => {
const [error, setError] = useState(null);
return (
<ErrorContext.Provider value={{ setError }}>
{children}
{error && (
<Toast.Root>
<Toast.Title>Ошибка</Toast.Title>
<Toast.Description>{error}</Toast.Description>
</Toast.Root>
)}
</ErrorContext.Provider>
);
};
export const useError = () => useContext(ErrorContext);
Любой компонент может использовать useError для
отображения ошибок, что позволяет избежать дублирования логики в каждом
компоненте Radix UI.
Некоторые компоненты, такие как Dialog или
Popover, часто используют динамический контент с сервера. В
таких случаях важно:
Spinner, Progress) до завершения
запроса.Пример с Dialog:
import * as Dialog from '@radix-ui/react-dialog';
import { useState, useEffect } from 'react';
function UserDialog({ userId, fetchUser }) {
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
fetchUser(userId)
.then(setUser)
.catch((err) => setError(err.message));
}, [userId]);
return (
<Dialog.Root>
<Dialog.Trigger>Открыть профиль</Dialog.Trigger>
<Dialog.Content>
{error && <div>Ошибка: {error}</div>}
{!error && !user && <div>Загрузка...</div>}
{user && <div>Имя: {user.name}</div>}
</Dialog.Content>
</Dialog.Root>
);
}
Такой подход позволяет компонентам оставаться предсказуемыми, а ошибки сервера — легко локализуемыми и информативными.
Toast для кратких уведомлений об ошибках,
Form.Message — для ошибок полей формы.Эти практики обеспечивают чистый, доступный и предсказуемый интерфейс при работе с Radix UI и серверными данными.