Контролируемые поля

Haunted — это современная библиотека для создания веб-компонентов с использованием реактивного подхода, основанного на хуках, аналогично React. Контролируемые поля в Haunted играют ключевую роль при управлении состоянием форм и элементов ввода.


Основы контролируемых компонентов

Контролируемое поле — это элемент формы (например, <input>, <textarea> или <select>), значение которого полностью управляется состоянием компонента. Состояние хранится в переменной, а любое изменение поля синхронизируется с этим состоянием через функцию обновления. Такой подход обеспечивает единый источник правды и предсказуемое поведение интерфейса.

Пример минимального контролируемого поля в Haunted:

import { html, component } from 'haunted';
import { useState } from 'haunted';

function TextInput() {
  const [value, setValue] = useState('');

  return html`
    <input
      type="text"
      .value=${value}
      @input=${e => setValue(e.target.value)}
    />
    <p>Вы ввели: ${value}</p>
  `;
}

customElements.define('text-input', component(TextInput));

Ключевые моменты:

  • Использование .value=${value} вместо value=${value} гарантирует, что свойство DOM обновляется напрямую.
  • Событие @input перехватывает пользовательский ввод и обновляет состояние через setValue.
  • Состояние value является единственным источником правды для этого поля.

Свойство vs Атрибут

Haunted различает DOM-атрибуты и свойства. Атрибуты устанавливаются в HTML при рендеринге, но не изменяются динамически при обновлении состояния. Для контролируемых полей необходимо использовать привязку к свойствам (.value), чтобы изменения состояния напрямую отражались на элементе.

Пример ошибки при использовании атрибута:

<input type="text" value=${value} /> <!-- Не контролируется корректно -->

В этом случае значение будет установлено только при первоначальном рендере и не будет обновляться при изменении состояния.


Обработка разных типов полей

Текстовые поля и textarea

Для <input type="text"> и <textarea> используется одинаковая схема:

const [text, setText] = useState('');

html`<textarea .value=${text} @input=${e => setText(e.target.value)}></textarea>`;

Флажки и переключатели

Для <input type="checkbox"> или <input type="radio"> контролируемое состояние хранится в булевом значении:

const [checked, setChecked] = useState(false);

html`<input type="checkbox" .checked=${checked} @change=${e => setChecked(e.target.checked)} />`;

Обратите внимание, что используется .checked вместо .value.

Селекторы

Для <select> контролируемое состояние хранит выбранное значение:

const [selected, setSelected] = useState('option1');

html`
  <select .value=${selected} @change=${e => setSelected(e.target.value)}>
    <option value="option1">Опция 1</option>
    <option value="option2">Опция 2</option>
  </select>
`;

Множественные поля и форма

При работе с формами, содержащими несколько контролируемых элементов, состояние часто организуется в объект:

const [form, setForm] = useState({ name: '', email: '' });

function updateField(e) {
  const { name, value } = e.target;
  setForm({ ...form, [name]: value });
}

html`
  <form>
    <input name="name" .value=${form.name} @input=${updateField} />
    <input name="email" .value=${form.email} @input=${updateField} />
    <p>Имя: ${form.name}, Email: ${form.email}</p>
  </form>
`;

Такой подход облегчает управление сложными формами и позволяет централизованно обрабатывать изменения.


Реактивность и ререндер

Haunted автоматически вызывает ререндер компонента при изменении состояния через useState. Для контролируемых полей это означает:

  • Любое изменение setValue мгновенно обновляет DOM.
  • Состояние всегда синхронизировано с отображением.
  • Нет необходимости вручную следить за изменениями в UI.

Важно избегать прямой модификации DOM без использования состояния, иначе контролируемость поля будет нарушена.


Практические рекомендации

  1. Использовать хуки состояния для всех управляемых полей. Это упрощает отладку и предсказуемость.
  2. Привязывать свойства DOM (.value, .checked). Атрибуты не подходят для динамических изменений.
  3. Обрабатывать события input для текста и change для чекбоксов/селекторов. Это обеспечивает правильную реактивность.
  4. Хранить состояние формы в объекте, если элементов несколько. Это уменьшает количество отдельных хуков и делает код структурированным.
  5. Не менять значение напрямую через DOM. Все обновления должны идти через useState.

Контролируемые поля в Haunted — это фундаментальная техника построения предсказуемых и реактивных форм. Использование хуков и привязки свойств позволяет создавать интерфейсы, где данные всегда синхронизированы с отображением, а компоненты остаются чистыми и управляемыми.