Глобальное состояние

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

Основы глобального состояния

В Haunted глобальное состояние реализуется через сторонние реактивные хранилища или с помощью встроенных хуков, таких как useStore. Основная идея заключается в создании объекта состояния, который может подписывать компоненты на изменения своих свойств. Каждый раз, когда состояние изменяется, подписанные компоненты автоматически перерисовываются.

Простейший пример создания глобального состояния:

import { store, useStore } from 'haunted';

const appState = store({
  user: { name: 'Иван', loggedIn: false },
  theme: 'light'
});

Здесь store создаёт реактивный объект, на который можно подписываться в компонентах с помощью useStore.

Подписка на глобальное состояние

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

import { html } from 'haunted';

function UserPanel() {
  const state = useStore(appState);

  return html`
    <div>
      <p>Пользователь: ${state.user.name}</p>
      <p>Статус: ${state.user.loggedIn ? 'В сети' : 'Не в сети'}</p>
      <button @click=${() => (state.user.loggedIn = !state.user.loggedIn)}>
        Переключить статус
      </button>
    </div>
  `;
}
customElements.define('user-panel', UserPanel);

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

  • useStore(appState) возвращает актуальное состояние.
  • Изменение любого свойства в объекте appState автоматически инициирует обновление компонентов.
  • Поддерживается вложенная реактивность: изменения в объектах и массивах также отслеживаются.

Разделение состояния на модули

Для больших приложений рекомендуется структурировать глобальное состояние по модулям, чтобы избежать монолитного объекта. Это позволяет создавать отдельные хранилища для пользователей, настроек, уведомлений и других частей приложения.

const userStore = store({ name: 'Иван', loggedIn: false });
const themeStore = store({ theme: 'light' });

Компоненты подключаются только к тем хранилищам, которые им необходимы, что снижает излишние перерисовки и повышает производительность.

Производные состояния

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

import { derived } from 'haunted';

const isUserLoggedIn = derived(userStore, state => state.loggedIn);

function LoginStatus() {
  const loggedIn = useStore(isUserLoggedIn);
  return html`<p>Статус: ${loggedIn ? 'В сети' : 'Не в сети'}</p>`;
}
customElements.define('login-status', LoginStatus);

Производные состояния позволяют создавать чистые, декларативные компоненты, которые обновляются автоматически при изменении базового состояния.

Асинхронные обновления

Для интеграции с API и асинхронными операциями можно напрямую модифицировать store после завершения запроса:

async function fetchUser() {
  const response = await fetch('/api/user');
  const data = await response.json();
  userStore.user = data;
}

Haunted гарантирует, что все подписанные компоненты обновятся после изменения данных.

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

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

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