Haunted — это библиотека для создания веб-компонентов с реактивным рендерингом, построенная на основе стандартов Web Components и функциональной концепции Hooks, похожей на React. Одной из ключевых особенностей является работа с мутабельными значениями, которые позволяют управлять состоянием компонентов более гибко и эффективно.
Мутабельные значения (mutable values) — это объекты, содержащие
внутреннее состояние, которое может изменяться без необходимости полного
пересоздания компонента. В Haunted они реализуются через функцию
useMutable, которая предоставляет ссылку на текущее
значение и механизм для его обновления.
Сигнатура useMutable:
const state = useMutable(initialValue);
initialValue — начальное значение, которое может быть
любого типа: объект, массив, число, строка.state — объект с единственным свойством
current, через которое производится доступ и изменение
значения.import { component, useMutable, html } from 'haunted';
function Counter() {
const counter = useMutable(0);
const increment = () => {
counter.current += 1;
};
return html`
<div>
<p>Счётчик: ${counter.current}</p>
<button @click=${increment}>Увеличить</button>
</div>
`;
}
customElements.define('my-counter', component(Counter));
В этом примере:
counter — мутабельное значение.counter.current автоматически триггерит
повторный рендер компонента.setState).В Haunted существует также useState, однако ключевое
отличие заключается в том, что useState возвращает массив
[value, setValue], а useMutable — объект с
.current.
Преимущества useMutable:
Недостатки:
Мутабельные значения особенно удобны для массивов и объектов, когда нужно изменять отдельные элементы без пересоздания всего объекта.
Пример с массивом:
function TodoList() {
const todos = useMutable([]);
const addTodo = (text) => {
todos.current.push({ text, done: false });
};
const toggleTodo = (index) => {
todos.current[index].done = !todos.current[index].done;
};
return html`
<ul>
${todos.current.map((todo, i) => html`
<li @click=${() => toggleTodo(i)} style="text-decoration: ${todo.done ? 'line-through' : 'none'};">
${todo.text}
</li>
`)}
</ul>
<button @click=${() => addTodo('Новая задача')}>Добавить</button>
`;
}
todos.current автоматически обновляет
DOM.Для больших компонентов с множеством взаимосвязанных состояний
useMutable позволяет:
Пример:
function Dashboard() {
const user = useMutable({ name: 'Алексей', age: 28 });
const notifications = useMutable([]);
const addNotification = (msg) => notifications.current.push(msg);
const updateName = (newName) => user.current.name = newName;
return html`
<div>
<h2>Пользователь: ${user.current.name}</h2>
<p>Возраст: ${user.current.age}</p>
<ul>
${notifications.current.map(n => html`<li>${n}</li>`)}
</ul>
</div>
`;
}
user.current или
notifications.current не влияет на другие части компонента,
пока они не используются в шаблоне.Мутабельные значения хорошо работают совместно с
useEffect для отслеживания изменений и выполнения побочных
эффектов:
import { useEffect } from 'haunted';
function Timer() {
const time = useMutable(0);
useEffect(() => {
const id = setInterval(() => time.current += 1, 1000);
return () => clearInterval(id);
}, []);
return html`<p>Время: ${time.current} сек</p>`;
}
time.current автоматически обновляет
отображение.useEffect корректно очищает таймер при размонтировании
компонента.number,
string) useMutable удобен для упрощённого
синтаксиса, но можно использовать useState для стандартного
подхода.useMutable
позволяет изменять вложенные элементы без копирования..current — это
гарантирует реактивность.Мутабельные значения в Haunted обеспечивают мощный инструмент для
управления состоянием компонентов, упрощают работу с динамическими
структурами данных и минимизируют избыточные рендеры. Правильное
использование useMutable повышает производительность и
делает код более лаконичным и предсказуемым.