Функция очистки

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


Использование useEffect и возвращаемой функции очистки

В Haunted хук useEffect позволяет выполнять побочные эффекты после рендера компонента:

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

function Timer() {
  useEffect(() => {
    const intervalId = setInterval(() => {
      console.log('tick');
    }, 1000);

    // Функция очистки возвращается из useEffect
    return () => {
      clearInterval(intervalId);
      console.log('Таймер остановлен');
    };
  });

  return html`<p>Смотрите консоль для событий таймера</p>`;
}

customElements.define('my-timer', component(Timer));

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

  • Возврат функции из useEffect создаёт механизм очистки, который вызывается перед повторным вызовом эффекта и при размонтировании компонента.
  • Эта функция используется для освобождения ресурсов, отмены таймеров, подписок и других асинхронных операций.
  • Если useEffect не возвращает функцию, очистка выполняться не будет.

Повторный вызов эффекта

useEffect может принимать массив зависимостей вторым аргументом:

useEffect(() => {
  const handleResize = () => console.log(window.innerWidth);
  window.addEventListener('resize', handleResize);

  return () => window.removeEventListener('resize', handleResize);
}, []); // Пустой массив — эффект выполнится один раз

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

  • Если массив зависимостей пустой ([]), эффект выполняется один раз при монтировании, а функция очистки — при размонтировании.
  • Если массив содержит значения ([propA, stateB]), эффект будет повторно выполняться при изменении этих значений, а перед каждым повторным вызовом будет вызвана функция очистки.

Очистка асинхронных операций

Функция очистки особенно важна для асинхронных процессов, чтобы избежать утечек памяти и конфликтов состояния:

useEffect(() => {
  let cancelled = false;

  fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => {
      if (!cancelled) {
        console.log('Полученные данные:', data);
      }
    });

  return () => {
    cancelled = true;
    console.log('Запрос отменён');
  };
}, []);

Объяснение:

  • Локальная переменная cancelled позволяет игнорировать результат запроса, если компонент размонтирован до завершения операции.
  • Без функции очистки данные могли бы попытаться обновить компонент, который уже не существует, что вызвало бы ошибки.

Взаимодействие с другими хуками

Функции очистки не ограничиваются только useEffect. Любой хук, который создает подписки или ресурсы, может использовать схему возврата функции очистки:

  • useReducer с побочными эффектами.
  • useState в сочетании с useEffect для синхронизации состояний.
  • Пользовательские хуки для абстрагирования логики.

Пример пользовательского хука с очисткой:

import { useState, useEffect } from 'haunted';

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const onRes ize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', onResize);

    return () => window.removeEventListener('resize', onResize);
  }, []);

  return width;
}

Практические рекомендации

  • Всегда возвращать функцию очистки, если создаются таймеры, подписки, сокеты или асинхронные операции.
  • Функция очистки должна быть чистой и безопасной, чтобы не вызывать побочные эффекты сама по себе.
  • Использование пустого массива зависимостей предотвращает ненужные повторные вызовы и защищает от лишних ресурсов.

Итоговые свойства функции очистки

  1. Автоматическое выполнение при размонтировании компонента.
  2. Вызов перед повторным эффектом при изменении зависимостей.
  3. Защита от утечек памяти и ошибок обновления несуществующих компонентов.
  4. Гибкость — подходит для таймеров, подписок, асинхронных запросов и пользовательских хуков.

Функция очистки является неотъемлемой частью эффективного управления состоянием и ресурсами в Haunted, обеспечивая корректное поведение компонентов и стабильность приложения.