Объявление состояния

В библиотеке Haunted состояние компонента управляется с помощью хука useState. Это ключевой механизм для хранения и обновления данных внутри веб-компонента, который позволяет автоматически перерисовывать DOM при изменении значений.

Хук useState

Сигнатура хука выглядит следующим образом:

const [state, setState] = useState(initialValue);
  • state — текущее значение состояния.
  • setState — функция для обновления состояния. Любое её использование вызывает повторный рендер компонента.
  • initialValue — начальное значение состояния, которое может быть любого типа: примитив, объект, массив или функция.

Пример объявления состояния:

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

function Counter() {
  const [count, setCount] = useState(0);

  return html`
    <div>
      <p>Счет: ${count}</p>
      <button @click=${() => setCount(count + 1)}>Увеличить</button>
    </div>
  `;
}

customElements.define('my-counter', component(Counter));

В этом примере count хранит текущее значение счётчика, а setCount обновляет его и автоматически инициирует повторный рендер.

Инициализация состояния через функцию

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

const [data, setData] = useState(() => fetchDataFromLocalStorage());

Использование функции экономит ресурсы, так как вычисление значения происходит только один раз, а не при каждом рендере.

Множественные состояния

В Haunted можно объявлять несколько независимых состояний внутри одного компонента:

function Form() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  return html`
    <input
      type="text"
      .value=${name}
      @input=${e => setName(e.target.value)}
    />
    <input
      type="email"
      .value=${email}
      @input=${e => setEmail(e.target.value)}
    />
  `;
}

Каждое состояние управляется отдельно, что обеспечивает чистоту и предсказуемость логики компонента.

Состояние объектов и массивов

При использовании объектов или массивов нужно помнить, что setState заменяет значение целиком. Чтобы обновить часть структуры, необходимо создавать новый объект или массив:

const [user, setUser] = useState({ name: 'Иван', age: 25 });

// Обновление одного свойства
setUser({ ...user, age: 26 });

// Для массивов
const [items, setItems] = useState([1, 2, 3]);
setItems([...items, 4]);

Такой подход гарантирует корректное срабатывание повторного рендера.

Зависимость от предыдущего состояния

Если новое значение зависит от предыдущего, лучше использовать функциональный вызов setState:

setCount(prevCount => prevCount + 1);

Это предотвращает ошибки при асинхронных обновлениях или нескольких последовательных вызовах setState.

Связь состояния и шаблонов

Haunted использует библиотеку lit-html для шаблонов. Любые изменения состояния автоматически отражаются в DOM без ручного обновления:

return html`
  <p>Текущее значение: ${state}</p>
`;

Каждое использование ${state} в шаблоне создаёт реактивную привязку к значению состояния.

Советы по оптимизации

  • Минимизировать количество состояний, объединяя связанные данные в один объект.
  • Использовать функции для вычисления начального состояния при дорогостоящих операциях.
  • Применять функциональный setState, когда новое значение зависит от старого.
  • Избегать мутаций объектов и массивов напрямую, всегда создавать новые копии.

Особенности Haunted

Haunted строится поверх Web Components и реактивной модели lit-html, поэтому состояние напрямую влияет на рендеринг, а объявление через useState обеспечивает компактный и управляемый синтаксис. Каждый вызов setState безопасен для асинхронных обновлений и не требует дополнительных методов жизненного цикла.