Кастомні хуки
Що таке кастомний хук
Кастомний хук - це звичайна JS-функція, ім'я якої починається з use, і всередині якої використовуються інші хуки React (useState, useEffect тощо).
Він потрібен, щоб винести і перевикористовувати логіку (стан, ефекти, підписки), не дублюючи її в компонентах.
Ідея: «поділися поведінкою, а не розміткою». Компонент лишається чистим, UI - окремо.
Як зробити (мікро-приклади)
1) Базовий: useToggle
javascript
import { useState, useCallback } from "react";
export function useToggle(initial = false) {
const [on, setOn] = useState(initial);
const toggle = useCallback(() => setOn(v => !v), []);
const setTrue = useCallback(() => setOn(true), []);
const setFalse = useCallback(() => setOn(false), []);
return { on, toggle, setTrue, setFalse };
}2) З побічним ефектом і очищенням: useDebounce
javascript
import { useEffect, useState } from "react";
export function useDebounce(value, delay = 300) {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const id = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(id); // cleanup
}, [value, delay]);
return debounced;
}3) З локальним сховищем: useLocalStorage
javascript
import { useEffect, useState } from "react";
export function useLocalStorage(key, initial) {
const [state, setState] = useState(() => {
const raw = localStorage.getItem(key);
return raw != null ? JSON.parse(raw) : initial;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(state));
}, [key, state]);
return [state, setState]; // знайомий інтерфейс, як у useState
}Правила (обмеження) хуків - must know
- Ім'я з
useФункція має називатисяuseSomething. Це не "магія", а домовленість, яку перевіряє лінтер. - Викликай хуки тільки на верхньому рівні Не можна всередині умов, циклів, вкладених функцій. Порядок викликів має бути однаковим на кожному рендері.
javascript
// погано
if (cond) { useEffect(...); }
// добре
useEffect(() => { if (cond) {/*...*/} }, [cond]);- Викликай хуки тільки з React-функцій З функціональних компонентів або інших хуків. Не зі звичайних функцій, не з обробників подій, не з класів.
- Кастомні хуки - це синхронні функції
Сам хук не має бути
async. Асинхронність - всередині ефектів. - Дотримуйся
exhaustive-depsЗалежності ефектів/мемоізацій мають бути коректними. Використовуйeslint-plugin-react-hooksдля контролю. - Не змішуй відповідальність Хук - про одну задачу (fetch, toggle, форми, синхронізація зі сховищем тощо). Маленькі, композиційні хуки кращі за один "гіга-хук".
- Стабільні посилання назовні
Якщо хук повертає функції/об'єкти, мемоізуй їх (
useCallback/useMemo), щоб споживачі не ререндерилися зайвий раз. - Не рендерить UI Хук повертає дані/методи, а не JSX. Малювати - задача компонентів.
- Особливості SSR
Усе, що залежить від
window/document/localStorage, перевіряй в ефектах або умовно (на сервері цих API немає).
Коли робити кастомний хук
- Повторюєш один і той самий
useEffect + useStateу кількох компонентах. - Потрібно інкапсулювати складну логіку (форми, запити, веб-сокети, синхронізація URL↔state).
- Хочеш надати чистий, тестований API для поведінки.
Рекомендації щодо API хуків
- Повертай примітивний і передбачуваний контракт (масив, як у
useState, або об'єкт з іменованими полями). - Документуй залежності (що передаємо в хук, що він повертає).
- Мінімізуй зовнішні ефекти: усе побічне - в
useEffectз акуратнимcleanup.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.