Состояние форм – отдельная тема для обсуждения. Существует два подхода к обработке состояния формы. Один из них отдает контроль состояния самой форме, другой предполагает его хранение в пользовательском приложении. Оба подхода имеют свои плюсы и минусы, которые обязательно надо знать при выборе того или иного решения.
В документации React такие подходы называют контролируемыми и неконтролируемыми формами. Эти названия довольно точно описывают происходящее, поэтому здесь мы будем использовать ту же терминологию.
Неконтролируемые формы
Подход, при котором состояние формы хранится внутри самой формы и извлекается только при ее отправке. Это привычный способ работы с формой вне фреймворков:
form.addEventListener('submit', (e) => {
const formData = new FormData(e.target);
// Обработка данных, например, отправка на сервер
});
К достоинствам этого способа относят:
- Простоту. Мало кода, не нужно хранить состояние.
- Скорость. Браузер делает всю работу сам. Минимум вмешательства со стороны пользовательского кода.
Несмотря на легкость и очевидность, этот подход обладает одним недостатком. При таком подходе невозможно реагировать на изменения формы в процессе ее заполнения. Где это может быть нужно? Вот несколько примеров:
- Автодополнение. Выпадающие списки зависят от того, что было набрано.
- Валидация в процессе набора. Часто реализуется в виде красной рамки вокруг поля для ввода.
- Моментальная фильтрация. Такое часто используется на сервисах бронирования или поиска товаров. Достаточно выбрать какой-то пункт меню, как сразу же меняется выборка.
В такой ситуации нам понадобятся контролируемые формы.
Контролируемые формы
При таком подходе состояние всех элементов формы отслеживается кодом приложения. Любое изменение анализируется и сохраняется. В зависимости от текущего состояния данных, код принимает решение что показать, а что нет. В таких формах зачастую даже нет кнопки отправки. Особенно там, где формы выполняют фильтрацию данных.
const state = {
registrationForm: {
state: 'valid',
data: {
name: '',
email: '',
},
errors: [],
},
};
// https://github.com/sindresorhus/on-change
const watchedState = onChange(state, (path, value) => {
if (path === 'registrationForm.state') {
if (value === 'invalid') {
// Отрисовка ошибок, хранящихся где-то в состоянии
// watchedState.registrationForm.errors
}
}
});
form.elements.name.addEventListener('change', (e) => {
watchedState.registrationForm.data.name = e.target.value;
// Действия: валидация, запросы, ...
});
form.elements.email.addEventListener('change', (e) => {
watchedState.registrationForm.data.email = e.target.value;
// Действия: валидация, запросы, ...
});
Если понадобится отправить эту форму, то сделать это будет даже проще, чем с неконтролируемыми формами. Данные уже извлечены из формы и готовы к отправке.
form.addEventListener('submit', (e) => {
// Обработка данных, например, отправка на сервер
// watchedState.registrationForm.data
});
Преимущества такого подхода:
- Позволяет реализовать любую реакцию во время изменения формы до или вместо ее отправки.
И недостатки:
- Значительно больше кода при ручной реализации.
- Они медленнее из-за большего числа действий (и возможно тяжелой реакции). Но проблема это или нет – зависит от конкретной ситуации.
Контролируемые формы требуют настолько больше кода, что работу с ними всячески пытаются автоматизировать. Создают библиотеки, например, garlic.js, которые в автоматическом режиме отслеживают изменение формы и предоставляют колбеки для реакции на эти изменения.
Особенно таких библиотек много для разных фреймворков. Например, в React их десятки.
Что использовать?
В чистом JS предпочтительнее неконтролируемые формы. Так намного проще и быстрее. И только в том случае, когда нужна мгновенная реакция, можно вводить контроль данных формы. Причем не обязательно переходить от одного способа к другому целиком. Можно использовать гибрид, вводить контроль только тех данных, где без этого никак.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.