React: Что такое Custom Hooks и как они позволяют вынести сложную логику API-запросов из визуальных компонентов?
Custom Hooks (пользовательские хуки) — это обычные JavaScript-функции, имя которых начинается с префикса `use`, и которые могут вызывать другие хуки React внутри себя. Они не являются частью официального API React, но следуют его соглашениям и позволяют переиспользовать логику с состоянием между несколькими компонентами.
## Зачем нужны Custom Hooks?
В типичном React-приложении компоненты быстро разрастаются: они одновременно отвечают за отображение UI и за получение данных, обработку ошибок, управление состоянием загрузки. Это нарушает принцип единственной ответственности и делает код трудночитаемым и нетестируемым.
Custom Hooks решают эту проблему, позволяя **вынести всю логику в отдельную функцию**, оставив компоненту только роль «отображателя».
## Пример: хук для API-запроса
Предположим, нам нужно загружать список пользователей. Без Custom Hook логика оказывается прямо в компоненте:
jsx
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(‘/api/users’)
.then(res => res.json())
.then(data => { setUsers(data); setLoading(false); })
.catch(err => { setError(err); setLoading(false); });
}, []);
if (loading) return ;
if (error) return ;
return
- {users.map(u =>
- {u.name}
)}
;
}
С Custom Hook логика переезжает в отдельный файл:
jsx
// useUsers.js
function useUsers() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(‘/api/users’)
.then(res => res.json())
.then(data => { setUsers(data); setLoading(false); })
.catch(err => { setError(err); setLoading(false); });
}, []);
return { users, loading, error };
}
// UserList.jsx
function UserList() {
const { users, loading, error } = useUsers();
if (loading) return ;
if (error) return ;
return
- {users.map(u =>
- {u.name}
)}
;
}
## Ключевые преимущества
1. **Переиспользование** — один хук можно подключить в десятки компонентов.
2. **Тестируемость** — логику хука тестируют отдельно от UI с помощью `@testing-library/react-hooks`.
3. **Читаемость** — компонент описывает только то, что показывать, а не как получать данные.
4. **Инкапсуляция** — детали реализации (retry, кэширование, отмена запроса через AbortController) скрыты внутри хука.
5. **Композиция** — хуки можно комбинировать: `usePaginatedUsers` может использовать внутри `useFetch`.
## Советы по практике
— Всегда начинайте имя с `use` — это не просто конвенция, это условие для работы линтера React.
— Параметризуйте хуки через аргументы (URL, метод, зависимости) для гибкости.
— Рассмотрите готовые решения: `react-query`, `SWR` — они построены на тех же принципах, но добавляют кэширование и синхронизацию.
Custom Hooks — один из самых мощных инструментов архитектуры React-приложений, позволяющий писать чистый, модульный и поддерживаемый код.
