Custom hook нужен не для красоты, а для переиспользования логики со state, эффектами и подписками. Если ты копируешь один и тот же useEffect, одну и ту же инициализацию состояния или одинаковую работу с API браузера в несколько компонентов, значит пора выносить это в отдельный хук.

Что делает custom hook полезным

Custom hook не рендерит UI и не “магически ускоряет React”. Он просто выносит связанную логику в функцию, которая сама использует хуки.

Есть два практических правила:

  • имя должно начинаться с use;
  • внутри хука действуют те же правила хуков, что и в компоненте.

Рабочий пример useLocalStorage

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

import { useEffect, useState } from "react";

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const savedValue = window.localStorage.getItem(key);

    if (savedValue !== null) {
      return JSON.parse(savedValue);
    }

    return initialValue;
  });

  useEffect(() => {
    window.localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
}

Здесь важны две вещи:

  • начальное значение читается лениво, только на первом рендере;
  • localStorage хранит строки, поэтому для объектов и массивов нужен JSON.stringify / JSON.parse.

Как использовать хук в компоненте

После этого хук можно использовать как обычную пару state и setState:

function Counter() {
  const [value, setValue] = useLocalStorage("day", 2);

  return (
    <button onClick={() => setValue((current) => current + 1)}>
      Day: {value}
    </button>
  );
}

После обновления страницы значение останется в localStorage, а компонент прочитает его при следующей инициализации.

Когда не нужно создавать custom hook

Не выноси код в hook слишком рано. Если логика живет в одном компоненте и не мешает чтению, отдельный хук только размажет контекст по файлам.

Custom hook оправдан, когда:

  • логика реально повторяется;
  • внутри есть состояние, подписка, эффект или работа с внешним API;
  • отдельное имя делает намерение понятнее, чем длинный кусок кода в компоненте.

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