Пользовательские Hooks
Пользовательские хуки — это функции, созданные разработчиком на основе встроенных хуков React. Они позволяют извлекать и повторно использовать логику компонентов, не дублируя код. Любой пользовательский хук должен начинаться с префикса use, чтобы React распознавал его как хук и применял правила хуков.
Зачем нужны
Часто в приложении возникает повторяющаяся логика: работа с локальным хранилищем, подписка на события, обработка состояния формы, кэширование данных. Вместо того чтобы писать один и тот же код в нескольких компонентах, вы выносите его в отдельную функцию-хук.
Преимущества:
- Логика изолирована и тестируема
- Компоненты становятся чище и короче
- Поведение легко переиспользовать
Пример: useLocalStorage
Этот хук инкапсулирует работу с localStorage и синхронизирует её с состоянием компонента:
import { useState, useEffect } from 'react';
function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T) => void] {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(`Ошибка при чтении ${key} из localStorage:`, error);
return initialValue;
}
});
const setValue = (value: T) => {
try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(`Ошибка при записи ${key} в localStorage:`, error);
}
};
return [storedValue, setValue];
}
Использование:
function App() {
const [name, setName] = useLocalStorage('userName', 'Гость');
return <input value={name} onChange={(e) => setName(e.target.value)} />;
}
Пример: useWindowSize
Хук для отслеживания размеров окна браузера:
import { useState, useEffect } from 'react';
function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowSize;
}
Использование:
function ResponsiveComponent() {
const { width } = useWindowSize();
return <div>Ширина окна: {width}px</div>;
}
Правила создания
- Имя всегда начинается с
use - Может вызывать другие хуки (
useState,useEffect,useContextи т.д.) - Не принимает JSX и не возвращает JSX — только данные и функции управления ими
- Должен быть чистым по отношению к компоненту: не зависит от конкретного UI
Когда не стоит создавать хук
- Если логика используется только в одном месте
- Если она слишком специфична и не поддаётся обобщению
- Если проще передать колбэк или использовать пропсы
Пользовательские хуки — мощный инструмент для абстракции поведения, но их следует применять осознанно, чтобы не усложнять архитектуру без необходимости.