Правила использования хуков

Haunted — это библиотека для создания веб-компонентов на основе стандартного API Custom Elements, вдохновлённая React-хуками. Хуки позволяют управлять состоянием компонентов, выполнять побочные эффекты и создавать переиспользуемую логику без необходимости создавать классы. Основное правило использования хуков заключается в том, что их вызовы должны быть согласованными между рендерами: каждый хук вызывается в одном и том же порядке при каждом обновлении компонента.


useState

Хук useState используется для создания локального состояния внутри компонента.

import { html, useState } from 'haunted';

function Counter() {
  const [count, setCount] = useState(0);

  return html`
    <div>
      <p>Счётчик: ${count}</p>
      <button @click=${() => setCount(count + 1)}>Увеличить</button>
    </div>
  `;
}

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

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

useEffect

Хук useEffect используется для выполнения побочных эффектов, таких как запросы к API или подписки на события.

import { useEffect } from 'haunted';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => setSeconds(s => s + 1), 1000);
    return () => clearInterval(interval);
  }, []);
  
  return html`<p>Прошло секунд: ${seconds}</p>`;
}

Особенности использования:

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

useRef

useRef создаёт объект, который сохраняется между рендерами и не вызывает повторного рендера при изменении.

import { useRef } from 'haunted';

function InputFocus() {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focus();
  };

  return html`
    <input ref=${inputRef} />
    <button @click=${focusInput}>Фокус</button>
  `;
}

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

  • Полезен для сохранения ссылок на DOM-элементы или других значений, которые не требуют повторного рендера.
  • Объект возвращается один раз и сохраняется между всеми рендерами.

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

Haunted позволяет создавать собственные хуки для переиспользования логики:

import { useState, useEffect } from 'haunted';

function useFetch(url) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData);
  }, [url]);

  return data;
}

function UserList() {
  const users = useFetch('https://jsonplaceholder.typicode.com/users');

  return html`
    <ul>
      ${users ? users.map(u => html`<li>${u.name}</li>`) : html`<li>Загрузка...</li>`}
    </ul>
  `;
}

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

  • Пользовательский хук — это функция, которая может использовать другие хуки.
  • Все хуки внутри пользовательского хука должны вызываться в одном и том же порядке при каждом рендере.
  • Нельзя вызывать хуки условно или внутри циклов.

Правила использования хуков

  1. Вызов только на верхнем уровне компонента Нельзя вызывать хуки внутри условий, циклов или вложенных функций. Это гарантирует, что порядок вызова хуков остаётся неизменным.

  2. Вызов только внутри функций-компонентов или пользовательских хуков Хуки не могут вызываться в обычных функциях или методах классов.

  3. Соблюдение порядка вызова Если порядок вызова хуков меняется между рендерами, Haunted потеряет соответствие состояния, что приведёт к багам.

  4. Чистка побочных эффектов Любой эффект, который создаёт подписки, таймеры или внешние ресурсы, должен возвращать функцию очистки.

  5. Минимизация количества рендеров Использование хуков не должно приводить к лишним обновлениям. Следует контролировать зависимости и избегать изменения состояния без необходимости.


Советы по архитектуре с хуками

  • Разделять логику и отображение: хуки должны отвечать за состояние и эффекты, а html за рендеринг.
  • Компоненты должны быть небольшими и однозначными: один компонент — одна задача.
  • Использовать пользовательские хуки для повторяемой логики: это повышает читаемость и поддерживаемость кода.

Haunted предоставляет мощный, но строгий подход к управлению состоянием и эффектами через хуки. Соблюдение правил вызова и порядка хуков является ключом к стабильным и предсказуемым компонентам.