Валидация форм является важным аспектом разработки интерактивных
веб-приложений. В Preact подход к валидации форм строится на управлении
состоянием компонентов и контролируемых элементах формы. Контролируемый
компонент — это элемент формы, значение которого полностью управляется
состоянием компонента через useState или другие хуки.
Пример контролируемого текстового поля:
import { h } from 'preact';
import { useState } from 'preact/hooks';
function LoginForm() {
const [email, setEmail] = useState('');
const handleChange = (e) => {
setEmail(e.target.value);
};
return (
<form>
<input
type="email"
value={email}
onIn put={handleChange}
placeholder="Введите email"
/>
</form>
);
}
Ключевой момент: значение поля привязано к состоянию компонента. Это позволяет легко выполнять проверку данных при вводе или при отправке формы.
Для валидации на лету можно использовать дополнительное состояние для ошибок:
const [error, setError] = useState('');
const validateEmail = (value) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(value) ? '' : 'Некорректный email';
};
const handleChange = (e) => {
const value = e.target.value;
setEmail(value);
setError(validateEmail(value));
};
Вывод ошибки:
<p style={{ color: 'red' }}>{error}</p>
Таким образом, ошибки отображаются динамически, а состояние компонента всегда актуально.
Иногда проверка всех полей выполняется при попытке отправки формы:
const handleSubmit = (e) => {
e.preventDefault();
const emailError = validateEmail(email);
if (emailError) {
setError(emailError);
return;
}
console.log('Форма отправлена', email);
};
Обработка событий onSubmit позволяет предотвратить
отправку некорректных данных.
Для больших форм с несколькими полями используется объект состояния для хранения значений и ошибок:
const [formData, setFormData] = useState({ email: '', password: '' });
const [formErrors, setFormErrors] = useState({});
const handleChange = (field) => (e) => {
const value = e.target.value;
setFormData({ ...formData, [field]: value });
setFormErrors({ ...formErrors, [field]: '' });
};
const validateForm = () => {
const errors = {};
if (!formData.email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
errors.email = 'Некорректный email';
}
if (formData.password.length < 6) {
errors.password = 'Пароль должен быть не менее 6 символов';
}
return errors;
};
const handleSubmit = (e) => {
e.preventDefault();
const errors = validateForm();
if (Object.keys(errors).length) {
setFormErrors(errors);
return;
}
console.log('Форма отправлена', formData);
};
Отображение ошибок для каждого поля:
<input
type="password"
value={formData.password}
onIn put={handleChange('password')}
placeholder="Введите пароль"
/>
<p style={{ color: 'red' }}>{formErrors.password}</p>
Для повторного использования логики валидации удобно создавать кастомные хуки:
import { useState } from 'preact/hooks';
function useForm(initialValues, validate) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const handleChange = (field) => (e) => {
const value = e.target.value;
setValues({ ...values, [field]: value });
if (errors[field]) {
setErrors({ ...errors, [field]: '' });
}
};
const handleSubmit = (onSuccess) => (e) => {
e.preventDefault();
const validationErrors = validate(values);
if (Object.keys(validationErrors).length) {
setErrors(validationErrors);
return;
}
onSuccess(values);
};
return { values, errors, handleChange, handleSubmit };
}
Использование хука:
const { values, errors, handleChange, handleSubmit } = useForm(
{ email: '', password: '' },
(vals) => {
const errs = {};
if (!vals.email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) errs.email = 'Некорректный email';
if (vals.password.length < 6) errs.password = 'Пароль слишком короткий';
return errs;
}
);
В сложных сценариях некоторые поля могут требовать проверки только при определённых условиях:
if (formData.subscribe && !formData.phone) {
errors.phone = 'Телефон обязателен при подписке';
}
Это позволяет гибко настраивать правила валидации в зависимости от состояния формы.
Современные Preact-формы строятся вокруг:
Такой подход упрощает поддержку больших форм, повышает читаемость кода и обеспечивает гибкость при реализации сложных правил валидации.