Синтаксис и параметры

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


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

Компоненты в Haunted создаются с помощью функции component, которая принимает функцию с параметрами и возвращает функцию, рендерящую шаблон:

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

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

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

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

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

  • component(fn) превращает обычную функцию в Web Component.
  • Функция может принимать объект параметров (props), которые передаются через атрибуты.
  • html используется для шаблонов, аналогично JSX, но в виде строк с интерполяцией.

Передача параметров

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

const el = document.createElement('my-counter');
el.initial = 10;  // свойство
document.body.appendChild(el);

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

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

Реактивное состояние

Для управления локальным состоянием применяется хук useState:

const [value, setValue] = useState(0);

Подробности работы:

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

События и биндинг

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

html`<button @click=${increment}>Нажми меня</button>`

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

  • События можно передавать напрямую через функцию.
  • Контекст компонента доступен через замыкания, что упрощает работу с состоянием.

Реактивные параметры

Параметры, переданные компоненту, автоматически отслеживаются:

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

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

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

const greeting = document.querySelector('my-greeting');
greeting.name = 'Алексей';

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

  • Haunted сравнивает старое и новое значение параметра, чтобы избежать лишних рендеров.
  • Можно использовать параметры совместно с состоянием для создания сложных реактивных интерфейсов.

Параметры по умолчанию и деструктуризация

Haunted поддерживает ES6 деструктуризацию и значения по умолчанию:

function UserCard({ user = { name: 'Гость', age: 0 } }) {
  return html`<p>${user.name}, ${user.age} лет</p>`;
}

Преимущества:

  • Удобно для установки дефолтных значений без лишних проверок.
  • Легко интегрировать с внешними данными и API.

Хуки и их параметры

Haunted предоставляет набор хуков для управления жизненным циклом и состоянием:

  • useState(initial) — локальное состояние.
  • useEffect(callback, dependencies) — реакция на изменения зависимостей.
  • useRef(initial) — сохранение ссылки на элемент или объект между рендерами.
  • useReducer(reducer, initialState) — управление сложным состоянием.

Пример с useEffect:

import { useEffect } from 'haunted';

function Timer({ interval = 1000 }) {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => setCount(c => c + 1), interval);
    return () => clearInterval(id);
  }, [interval]);

  return html`<p>Прошло: ${count} сек</p>`;
}

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

  • useEffect выполняется после рендера.
  • Возвращаемая функция используется для очистки ресурсов.
  • Зависимости контролируют повторные вызовы эффекта.

Поддержка слотов

Haunted полностью совместим с концепцией слотов Web Components:

function Card() {
  return html`<div class="card"><slot></slot></div>`;
}

Применение:

<my-card>
  <p>Содержимое карточки</p>
</my-card>
  • Слоты позволяют создавать гибкие и переиспользуемые компоненты.
  • Можно комбинировать с параметрами и состоянием для динамического содержимого.

Итоговая структура синтаксиса

  1. Определение компонента через component(fn).
  2. Передача параметров через атрибуты или свойства.
  3. Управление локальным состоянием через useState.
  4. Реакция на события с помощью @event.
  5. Использование хуков для побочных эффектов и ссылок.
  6. Работа со слотами для вложенного контента.

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