Типы для хуков

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


useState

useState — основной хуковый инструмент для управления состоянием внутри компонента. В Haunted его синтаксис схож с React:

import { useState } from 'haunted';

const [state, setState] = useState(initialValue);

Типизация useState в TypeScript позволяет явно указать тип значения состояния:

const [count, setCount] = useState<number>(0);
  • count — переменная состояния типа number.
  • setCount — функция для обновления состояния, принимающая либо новое значение, либо функцию (prev: number) => number.

Использование функций обновления особенно полезно при зависимостях от предыдущего состояния:

setCount(prev => prev + 1);

useEffect

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

useEffect(() => {
  // код эффекта
  return () => {
    // очистка
  };
}, [dependencies]);

В TypeScript важно правильно указать типы:

useEffect((): void => {
  const timer = setInterval(() => console.log(count), 1000);
  return () => clearInterval(timer);
}, [count]);

Особенности типизации:

  • Возвращаемое значение должно быть либо void, либо функция очистки () => void.
  • Зависимости — массив значений, корректная типизация которых предотвращает ошибки сравнения.

useRef

useRef используется для хранения ссылок на DOM-элементы или значения, которые не должны вызывать ререндер при изменении. В Haunted:

import { useRef } from 'haunted';

const inputRef = useRef<HTMLInputElement>();

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

  • inputRef.current может быть undefined до первого рендера.
  • Для типов объектов указывают конкретный класс элемента (HTMLDivElement, HTMLButtonElement и т.д.).
  • Можно хранить произвольные значения, не связанные с DOM:
const timerId = useRef<number | null>(null);

useReducer

useReducer в Haunted аналогичен React: используется для более сложного управления состоянием.

type State = { count: number };
type Action = { type: 'increment' | 'decrement' };

const reducer = (state: State, action: Action): State => {
  switch(action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'decrement': return { count: state.count - 1 };
  }
};

const [state, dispatch] = useReducer(reducer, { count: 0 });

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


useCallback

useCallback возвращает мемоизированную функцию, предотвращая её пересоздание на каждом рендере. В Haunted это важно для оптимизации ререндеров дочерних компонентов:

import { useCallback } from 'haunted';

const memoizedCallback = useCallback((value: number) => {
  console.log(value);
}, []);

Особенности типизации:

  • Явное указание типов аргументов и возвращаемого значения функции.
  • Массив зависимостей влияет на пересоздание функции.

useMemo

useMemo используется для мемоизации вычислений. В Haunted позволяет избежать повторных вычислений сложных выражений при каждом рендере:

import { useMemo } from 'haunted';

const doubled = useMemo((): number => count * 2, [count]);

Типизация:

  • Указывается тип возвращаемого значения: useMemo<number>(...).
  • Зависимости — строго типизированный массив, обычно соответствующий переменным, используемым в вычислении.

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

Haunted поддерживает создание пользовательских хуков, которые также можно типизировать:

function useCounter(initial: number): [number, () => void] {
  const [count, setCount] = useState<number>(initial);
  const increment = () => setCount(prev => prev + 1);
  return [count, increment];
}

const [count, increment] = useCounter(0);

Преимущества:

  • Возможность многократного переиспользования логики состояния.
  • Явная типизация возвращаемого массива [state, функция].

Общие рекомендации по типизации хуков

  1. Всегда указывать тип состояния: особенно для useState, чтобы предотвратить автоматическое приведение типов.
  2. Типизировать зависимости в useEffect, useCallback и useMemo.
  3. Использовать интерфейсы или типы для сложных объектов состояния и действий.
  4. Проверять current у useRef на undefined перед доступом.
  5. Пользовательские хуки должны возвращать строго типизированные значения, чтобы избежать ошибок при деструктуризации.

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