Хуки и их эквиваленты в Inferno

Inferno предоставляет функциональный подход к созданию компонентов, аналогичный React, включая систему хуков. Хуки позволяют управлять состоянием, жизненным циклом и побочными эффектами без использования классовых компонентов. В Inferno их использование построено вокруг пакета inferno-hooks.

import { useState, useEffect } from 'inferno-hooks';

useState

useState создаёт локальное состояние в функциональном компоненте. Возвращает массив из текущего значения состояния и функции для его обновления.

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

  return (
    <button onCl ick={() => setCount(count + 1)}>
      Счётчик: {count}
    </button>
  );
}

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

  • Изменение состояния через setCount вызывает повторный рендер компонента.
  • Состояние сохраняется между рендерами.
  • Можно передавать функцию в setCount для вычисления нового состояния на основе предыдущего значения:
setCount(prevCount => prevCount + 1);

useEffect

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

useEffect(() => {
  const timer = setInterval(() => console.log('tick'), 1000);
  return () => clearInterval(timer); // очистка эффекта
}, []);

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

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

useRef

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

function FocusInput() {
  const inputRef = useRef(null);

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

  return (
    <div>
      <input ref={inputRef} />
      <button onCl ick={focus}>Фокус</button>
    </div>
  );
}

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

  • ref.current хранит текущее значение.
  • Используется для работы с DOM напрямую или хранения промежуточных значений.

useMemo и useCallback

useMemo оптимизирует вычисления, возвращая мемоизированное значение. useCallback мемоизирует функцию.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => doSomething(a), [a]);

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

  • Сокращение ненужных вычислений и перерисовок дочерних компонентов.
  • Улучшение производительности при работе с тяжёлыми вычислениями или сложными деревьями компонентов.

Эквиваленты хуков в классовых компонентах

Хотя Inferno ориентирован на функциональные компоненты с хуками, классовые компоненты также поддерживаются. Основные хуки имеют эквиваленты:

Хук Эквивалент в классе
useState this.state и this.setState
useEffect componentDidMount, componentDidUpdate, componentWillUnmount
useRef createRef и сохранение значения в свойстве класса
useMemo Кэширование значения вручную или через методы класса
useCallback Определение методов класса с мемоизацией вручную

Пример класса с состоянием и эффектами:

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
    this.increment = this.increment.bind(this);
  }

  componentDidMount() {
    console.log('Компонент смонтирован');
  }

  increment() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <button onCl ick={this.increment}>
        Счётчик: {this.state.count}
      </button>
    );
  }
}

Советы по использованию хуков в Inferno

  • Порядок хуков важен: все хуки должны вызываться в одном и том же порядке при каждом рендере.
  • Разделение логики: сложную логику состояния и эффектов лучше вынести в отдельные пользовательские хуки.
  • Мемоизация и производительность: useMemo и useCallback помогают избегать лишних перерисовок при передаче функций или объектов в дочерние компоненты.
  • Очистка эффектов: всегда возвращать функцию очистки из useEffect, чтобы предотвратить утечки памяти и некорректное поведение.

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

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

function useCounter(initialValue = 0) {
  const [count, setCount] = useState(initialValue);
  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);
  return { count, increment, decrement };
}

function Counter() {
  const { count, increment, decrement } = useCounter(10);
  return (
    <div>
      <button onCl ick={decrement}>-</button>
      {count}
      <button onCl ick={increment}>+</button>
    </div>
  );
}

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

Итоговые акценты

  • Inferno поддерживает почти все базовые хуки React через пакет inferno-hooks.
  • Хуки обеспечивают чистый функциональный подход к состоянию и побочным эффектам.
  • Для сложных компонентов возможно сочетание хуков с классами.
  • Правильная структура и мемоизация повышают производительность и предотвращают ошибки.

Использование хуков в Inferno позволяет создавать динамичные, производительные и легко поддерживаемые приложения, сохраняя при этом привычную для разработчиков с опытом в React парадигму.