Линтеры и форматтеры

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

Создание компонента

Компонент в Haunted создаётся функцией, которая возвращает шаблон в формате lit-html. Основная структура выглядит так:

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));

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

  • useState создаёт реактивное состояние внутри компонента.
  • Шаблон возвращается через html из lit-html, позволяя использовать привязку данных.
  • component оборачивает функцию в полноценный Web Component.

Работа с эффектами

Haunted поддерживает эффекты, аналогичные React Hooks, через useEffect. Они позволяют выполнять побочные действия при изменении состояния или при монтировании/размонтировании компонента.

import { useEffect } from 'haunted';

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

  useEffect(() => {
    console.log('Значение изменилось:', value);
    return () => console.log('Очистка эффекта');
  }, [value]);

  return html`
    <input type="text" .value=${value} @input=${e => setValue(e.target.value)}>
  `;
}

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

  • Второй аргумент — массив зависимостей. Эффект вызывается при их изменении.
  • Функция возвращает функцию очистки (cleanup), которая срабатывает перед повторным вызовом или при удалении компонента.

Пользовательские хуки

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

function useCounter(initial = 0) {
  const [count, setCount] = useState(initial);
  const increment = () => setCount(count + 1);
  return { count, increment };
}

function CounterDisplay() {
  const { count, increment } = useCounter();
  return html`
    <p>${count}</p>
    <button @click=${increment}>+</button>
  `;
}

Пользовательские хуки обеспечивают чистую и модульную архитектуру, особенно при большом количестве компонентов с похожей логикой.

Жизненный цикл компонента

Haunted поддерживает основные события жизненного цикла Web Components, но через хуки это упрощается:

  • useEffect с пустым массивом зависимостей [] срабатывает один раз при монтировании, аналог connectedCallback.
  • Возвращаемая функция выполняется при размонтировании, аналог disconnectedCallback.

Пример использования:

useEffect(() => {
  console.log('Компонент смонтирован');
  return () => console.log('Компонент размонтирован');
}, []);

Оптимизация рендеринга

Haunted автоматически перерисовывает компонент при изменении состояния, но возможны оптимизации:

  • Минимизировать количество состояний, чтобы уменьшить количество перерендеров.
  • Группировать связанные данные в один объект или массив.
  • Использовать useMemo для вычислений, зависящих от состояния, чтобы избежать лишних операций.
import { useMemo } from 'haunted';

const doubled = useMemo(() => count * 2, [count]);

Работа с атрибутами и свойствами

Haunted поддерживает реактивную привязку как к свойствам, так и к атрибутам. Свойства компонента можно передавать напрямую, а атрибуты автоматически конвертируются в строки.

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

customElements.define('my-greeting', component(Greeting));

Передача данных через атрибуты:

<my-greeting name="Анна"></my-greeting>

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

Стилизация компонентов

Стили можно применять через <style> внутри шаблона или через Shadow DOM.

return html`
  <style>
    p { color: blue; font-weight: bold; }
  </style>
  <p>${name}</p>
`;

Shadow DOM изолирует стили компонента от внешнего окружения, предотвращая нежелательные конфликты CSS.

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

Haunted позволяет легко работать с событиями через директиву @event:

<button @click=${() => dispatchEvent(new CustomEvent('increment'))}>+</button>

Кастомные события могут передавать данные через detail:

dispatchEvent(new CustomEvent('update', { detail: { value: 42 } }));

Интеграция с другими библиотеками

Haunted совместим с любыми библиотеками, использующими стандартные DOM API. Это делает возможной интеграцию с Redux, RxJS, D3, и другими, где данные можно просто прокидывать через свойства компонентов.


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