Haunted — это лёгкая библиотека для создания веб-компонентов на базе стандартов Web Components с использованием функционального подхода и реактивного состояния, вдохновлённая концепцией React Hooks. Она позволяет определять компоненты как функции, управлять их состоянием и жизненным циклом без необходимости использовать классы.
В отличие от традиционных классовых веб-компонентов, Haunted облегчает работу с состоянием, эффектами и реактивным рендерингом, сохраняя при этом совместимость с любыми современными браузерами и минимизируя накладные расходы.
Компоненты в Haunted создаются с помощью функции
component. Основная структура выглядит следующим
образом:
import { component, html, 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));
Ключевые моменты:
html — тег-функция для шаблонов, совместимая с
lit-html, позволяет вставлять переменные напрямую.useState — хук состояния, возвращает текущее значение и
функцию для его обновления.@ перед именем события
(@click).Haunted использует подход React-подобных хуков для управления состоянием и побочными эффектами. Основные хуки:
Позволяет создавать реактивное состояние:
const [value, setValue] = useState(initialValue);
value — текущее значение.setValue — функция обновления состояния, вызывающая
перерисовку компонента.Используется для выполнения побочных эффектов после рендера:
useEffect(() => {
console.log('Компонент обновился');
return () => console.log('Очистка эффекта при удалении компонента');
}, [value]);
Создаёт ссылку на DOM-элемент или произвольное значение:
const inputRef = useRef();
return html`<input ${ref(inputRef)} />`;
useRef сохраняет объект между рендерами.ref позволяет напрямую манипулировать
DOM.Haunted позволяет легко работать с свойствами веб-компонента.
function Greeting({ name }) {
return html`<p>Привет, ${name}!</p>`;
}
customElements.define('my-greeting', component(Greeting));
<my-greeting name="Мария"></my-greeting>
component:component(Greeting, { observedAttributes: ['name'] });
Haunted поддерживает нативные события и делегирование через
@event синтаксис:
html`<button @click=${handleClick}>Нажми меня</button>`
@event, будет вызвана с
объектом события.Haunted предоставляет хуки жизненного цикла, аналогичные React:
useConnected: вызывается при добавлении компонента в
DOM.useDisconnected: вызывается при удалении компонента из
DOM.useEffect с пустым массивом зависимостей
([]) можно использовать как componentDidMount
/ componentWillUnmount.useEffect(() => {
console.log('Монтирование компонента');
return () => console.log('Размонтирование компонента');
}, []);
Haunted использует лит-html для рендеринга, что обеспечивает:
Пример вложенного компонента:
function App() {
return html`
<div>
<my-counter></my-counter>
<my-greeting name="Алексей"></my-greeting>
</div>
`;
}
customElements.define('my-app', component(App));
Позволяет управлять сложным состоянием через редьюсер:
const [state, dispatch] = useReducer(reducer, initialState);
reducer(state, action) возвращает новое состояние.dispatch(action) инициирует обновление состояния.Haunted поддерживает контекст для передачи данных глубоко в дерево компонентов:
const ThemeContext = createContext('light');
useContext(ThemeContext).Haunted сочетает лёгкость веб-компонентов с мощью реактивного подхода и хуков, предоставляя удобный инструмент для построения современных интерфейсов без лишнего кода и сложной инфраструктуры.