Haunted — это минималистичная библиотека для создания веб-компонентов
на базе функциональных компонентов и реактивных хуков, вдохновлённая
React, но использующая нативные Web Components. Одной из ключевых
возможностей Haunted является управление состоянием и побочными
эффектами через хуки, аналогичные React Hooks, включая
useEffect и массив зависимостей.
useEffect и его
синтаксисuseEffect позволяет выполнять побочные эффекты после
рендера компонента, таких как работа с DOM, асинхронные запросы или
установка таймеров. Базовый синтаксис:
import { useEffect } from 'haunted';
useEffect(() => {
// Логика побочного эффекта
console.log('Компонент отрендерен');
return () => {
// Очистка эффекта
console.log('Компонент размонтирован');
};
}, [/* массив зависимостей */]);
Ключевой элемент — массив зависимостей (dependency
array). Он определяет, когда эффект должен повторно выполняться. Если
массив пустой [], эффект выполняется только один раз после
первого рендера. Если массив содержит переменные, эффект будет
срабатывать каждый раз при изменении любой из них.
Массив зависимостей выполняет две задачи:
Пример с массивом зависимостей:
import { html, component, useState, useEffect } from 'haunted';
function Counter() {
const [count, setCount] = useState(0);
const [step, setStep] = useState(1);
useEffect(() => {
console.log(`Счётчик обновился: ${count}`);
}, [count]); // Эффект срабатывает только при изменении count
return html`
<div>
<p>Счётчик: ${count}</p>
<button @click=${() => setCount(count + step)}>Увеличить</button>
<button @click=${() => setStep(step + 1)}>Изменить шаг (${step})</button>
</div>
`;
}
customElements.define('my-counter', component(Counter));
В этом примере эффект выводит сообщение в консоль только при
изменении count, игнорируя изменения step. Это
демонстрирует точечное реагирование на изменения
состояния через массив зависимостей.
Массив зависимостей сравнивает элементы по ссылке, а не по содержимому. Если в массиве находится объект, массив или функция, эффект будет выполняться при каждой генерации нового объекта, даже если его содержимое не изменилось.
useEffect(() => {
console.log('Объект изменился');
}, [{ value: 1 }]); // Всегда сработает, так как объект создаётся заново при каждом рендере
Чтобы избежать лишних вызовов, объекты нужно хранить в состоянии или
мемоизировать через useState или useMemo.
Функция очистки, возвращаемая из useEffect, срабатывает
перед повторным вызовом эффекта и при размонтировании
компонента. Это важно при работе с таймерами, подписками и сетевыми
соединениями:
useEffect(() => {
const timer = setInterval(() => console.log(count), 1000);
return () => clearInterval(timer);
}, [count]); // Каждый раз при изменении count старый таймер очищается
Если массив зависимостей пустой, функция очистки выполняется только при размонтировании компонента.
[] — эффект выполняется
один раз после первого рендера.Неправильное указание зависимостей может привести к багам или лишним рендерам. Например, использование переменной внутри эффекта без её добавления в массив зависимостей создаёт непредсказуемое поведение.
useEffect(() => {
let isMounted = true;
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
if (isMounted) {
setData(data);
}
}
fetchData();
return () => {
isMounted = false; // предотвращает обновление состояния после размонтирования
};
}, [url]); // Эффект срабатывает при изменении url
Массив зависимостей гарантирует, что новый запрос выполняется только при изменении URL, предотвращая лишние запросы и потенциальные утечки памяти.
Эффективное использование массива зависимостей делает Haunted мощным инструментом для управления состоянием и побочными эффектами в веб-компонентах.