Создание собственных хуков

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

Хуки определяются в объекте компонента через ключ hooks, где каждый ключ — это название события жизненного цикла, а значение — функция, выполняющая соответствующую задачу.

Пример базовой структуры хуков:

import { define, props } from 'skatejs';

const MyComponent = define('my-component', {
  props: {
    value: props.string
  },
  hooks: {
    connected(element) {
      console.log('Компонент добавлен в DOM', element);
    },
    disconnected(element) {
      console.log('Компонент удалён из DOM', element);
    }
  }
});

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

  • connected — вызывается при вставке элемента в DOM.
  • disconnected — вызывается при удалении элемента из DOM.
  • Функции хуков получают элемент или объект компонента как аргумент, что позволяет работать с его состоянием и свойствами.

Хуки и свойства компонента

SkateJS позволяет отслеживать изменения свойств компонента через хук propChanged. Этот хук вызывается каждый раз, когда изменяется значение свойства, и предоставляет возможность реагировать на это изменение:

hooks: {
  propChanged(element, data) {
    console.log(`Свойство ${data.name} изменилось с ${data.oldValue} на ${data.newValue}`);
  }
}

Параметры хука propChanged:

  • element — экземпляр компонента.

  • data — объект с информацией о изменении:

    • name — имя свойства, которое изменилось.
    • oldValue — предыдущее значение.
    • newValue — новое значение.

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

Пользовательские хуки

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

import { hook } from 'skatejs';

hook('log', (element, message) => {
  console.log(`[Log Hook] ${message}`, element);
});

Данный хук можно использовать в любом компоненте:

hooks: {
  log(element) {
    element.log('Компонент инициализирован');
  }
}

Особенности пользовательских хуков:

  • Можно передавать дополнительные аргументы через вызов хуков.
  • Хуки выполняются в порядке их объявления, что позволяет строить цепочки обработки.
  • Пользовательские хуки интегрируются с системными, например connected или propChanged.

Асинхронные хуки

Хуки в SkateJS могут быть асинхронными. Это особенно полезно при работе с сетевыми запросами, загрузкой данных или динамическим подключением шаблонов:

hooks: {
  async connected(element) {
    const response = await fetch('/api/data');
    element.data = await response.json();
    console.log('Данные загружены', element.data);
  }
}

Асинхронные хуки не блокируют рендеринг компонента и позволяют безопасно выполнять длительные операции без нарушения жизненного цикла.

Хуки рендеринга

Для работы с DOM существует хук rendered, который вызывается после того, как разметка компонента была вставлена в DOM. Он полезен для прямой манипуляции элементами или инициализации сторонних библиотек:

hooks: {
  rendered(element) {
    const button = element.querySelector('button');
    button.addEventListener('click', () => alert('Нажато'));
  }
}

Рекомендации по использованию:

  • Минимизировать прямую манипуляцию DOM внутри хуков, чтобы сохранить реактивность.
  • Использовать хуки для инициализации плагинов или компонентов сторонних библиотек.
  • Освобождать ресурсы в хуке disconnected, например удалять слушатели событий.

Композиция хуков

В SkateJS можно комбинировать несколько хуков одного типа для одного компонента. Это достигается через массив функций:

hooks: {
  connected: [
    (element) => console.log('Первый connected'),
    (element) => console.log('Второй connected')
  ]
}

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

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

Пример комплексного пользовательского хука для управления состоянием видимости элемента:

hook('visibility', (element, { show }) => {
  if (show) {
    element.style.display = '';
  } else {
    element.style.display = 'none';
  }
});

Использование в компоненте:

hooks: {
  connected(element) {
    element.visibility({ show: true });
  },
  propChanged(element, data) {
    if (data.name === 'visible') {
      element.visibility({ show: data.newValue });
    }
  }
}

Такая структура позволяет вынести логику управления видимостью в отдельный хук и переиспользовать его в других компонентах без дублирования кода.

Итоговые принципы работы с хуками

  • Хуки обеспечивают полный контроль над жизненным циклом компонента.
  • Пользовательские хуки повышают переиспользуемость кода и позволяют создавать модульные компоненты.
  • Асинхронные хуки и хук rendered расширяют возможности интеграции с внешними ресурсами и DOM.
  • Композиция хуков позволяет строить сложные сценарии без потери читаемости.

Эффективное использование хуков позволяет строить реактивные, гибкие и модульные веб-компоненты, полностью используя потенциал SkateJS.