Локальное состояние

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

useState: базовый инструмент локального состояния

Основной инструмент для работы с локальным состоянием — это хук useState. Он предоставляет компоненту переменную состояния и функцию для её изменения.

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

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

  return html`
    <div>
      <p>Текущее значение: ${count}</p>
      <button @click=${() => setCount(count + 1)}>Увеличить</button>
      <button @click=${() => setCount(count - 1)}>Уменьшить</button>
    </div>
  `;
}

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

Особенности useState:

  • Инициализация: Значение состояния задаётся при первом вызове хука.
  • Изменение состояния: Используется функция, возвращаемая хукoм, которая вызывает повторный рендер компонента.
  • Независимость: Каждое использование useState создаёт отдельную пару [state, setState], которая независима от других состояний в компоненте.

Ленивое вычисление начального состояния

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

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

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

Множественные состояния в одном компоненте

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

const [name, setName] = useState('');
const [age, setAge] = useState(0);

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

Использование локального состояния с эффектами

Для синхронизации состояния с внешними источниками данных используется useEffect. Локальное состояние может быть изменено в ответ на внешние события:

import { useEffect } from 'haunted';

function Clock() {
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    const interval = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(interval);
  }, []);

  return html`<p>Текущее время: ${time.toLocaleTimeString()}</p>`;
}

customElements.define('my-clock', component(Clock));

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

  • Эффекты могут зависеть от состояния, вызывая повторные вычисления.
  • Очистка эффектов предотвращает утечки памяти при удалении компонента.

Локальное состояние и события

Состояние часто обновляется в ответ на пользовательские действия. Haunted позволяет легко связывать события с функциями изменения состояния:

<button @click=${() => setCount(count + 1)}>Увеличить</button>

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

Совмещение с вычисляемыми значениями

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

const doubled = count * 2;

return html`<p>Двойное значение: ${doubled}</p>`;

Это позволяет избегать хранения избыточных данных и упрощает логику рендера.

Сложные объекты и массивы

Haunted корректно работает с объектами и массивами. Важно помнить, что useState не делает глубокого клонирования, поэтому обновления должны быть иммутабельными:

const [items, setItems] = useState([]);

function addItem(newItem) {
  setItems([...items, newItem]);
}

Изменения должны создавать новый объект или массив, чтобы Haunted смог отследить обновление состояния и перерендерить компонент.

Локальное состояние в повторно используемых компонентах

Использование useState внутри функций-компонентов обеспечивает, что каждый экземпляр компонента имеет своё отдельное состояние. Это особенно важно при создании коллекций элементов с идентичной логикой:

<my-counter></my-counter>
<my-counter></my-counter>

Каждый <my-counter> хранит своё собственное значение count и не влияет на другие экземпляры.

Рекомендации по работе с локальным состоянием

  • Использовать отдельные useState для логически различных данных.
  • Всегда создавать новые объекты при обновлении сложных структур.
  • Комбинировать с useEffect для синхронизации состояния с внешними источниками.
  • Минимизировать вычисления внутри рендера, вынося их в локальные функции или ленивую инициализацию.

Локальное состояние в Haunted — это компактный и мощный инструмент управления данными компонента, обеспечивающий реактивность, изоляцию и удобство организации логики. Его правильное применение позволяет создавать эффективные, поддерживаемые и легко расширяемые веб-компоненты.