Начальное состояние

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


Определение состояния

Состояние в Haunted создаётся с помощью хука useState. Этот хук возвращает массив из двух элементов:

  1. Текущее значение состояния
  2. Функция для обновления состояния

Пример базового синтаксиса:

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 задаётся значением 0. При вызове setCount компонент автоматически перерисовывается с новым значением.


Ленивое инициализирование состояния

Haunted поддерживает ленивое задание начального состояния через функцию, которая вызывается один раз при первом рендере. Это полезно, если вычисление начального значения ресурсоёмкое.

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

Преимущество такого подхода в том, что expensiveComputation() не будет вызываться при каждом рендере, а только один раз при инициализации компонента.


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

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

const [user, setUser] = useState({ name: 'Alice', age: 25 });

// Обновление поля объекта
setUser(prev => ({ ...prev, age: prev.age + 1 }));

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


Использование нескольких состояний

В Haunted можно использовать несколько независимых состояний в одном компоненте. Это позволяет изолировать различные логические части интерфейса:

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

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


Связь состояния и событий

Состояние часто обновляется в ответ на события, такие как клики, изменения ввода или асинхронные операции. Haunted поддерживает привязку событий через директиву @event:

<input type="text" @input=${e => setText(e.target.value)} />

В этом примере значение поля ввода автоматически сохраняется в состоянии text, а интерфейс может использовать это значение реактивно.


Начальное состояние и свойства компонента

Иногда начальное состояние компонента зависит от переданных свойств (props). Haunted предоставляет второй аргумент хука useState для такой интеграции:

function Greeting({ initialName }) {
  const [name, setName] = useState(initialName || 'Гость');

  return html`<p>Привет, ${name}!</p>`;
}

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


Асинхронная инициализация состояния

Начальное состояние может зависеть от асинхронных данных, например, загрузки с сервера. В таком случае обычно используют комбинацию useState и useEffect:

import { useEffect } from 'haunted';

function DataLoader({ url }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData);
  }, [url]);

  return html`
    <div>
      ${data ? html`<pre>${JSON.stringify(data, null, 2)}</pre>` : 'Загрузка...'}
    </div>
  `;
}

Первоначально состояние data равно null, затем обновляется после завершения асинхронного запроса. Компонент автоматически перерисовывается при получении данных.


Ключевые рекомендации при работе с начальным состоянием

  • Избегать мутаций: всегда создавать новый объект/массив при обновлении состояния.
  • Использовать ленивое инициализирование для дорогостоящих вычислений.
  • Разделять состояния, если они логически независимы.
  • Синхронизировать с props, если начальное состояние зависит от внешних данных.
  • Асинхронные операции реализовывать через useEffect, чтобы не блокировать первичный рендер.

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