Можно ли использовать useEffect в кастомном хуке
Что проверяют
Понимаете ли вы, что кастомный хук это обычная функция, которая вызывает другие хуки, и что на неё распространяются те же правила. Следом обычно спрашивают, делят ли два компонента, вызвавших один хук, общее состояние, и как в таком хуке отменять запрос.
Как отвечать
Да, и это основной сценарий кастомных хуков: вынести в useOnlineStatus, useDebounce или useWindowSize связку useState и useEffect с подпиской и отпиской. Что стоит проговорить:
- правила хуков: вызывать только на верхнем уровне, не внутри условий и циклов, имя начинать с
use. По префиксуeslint-plugin-react-hooksпонимает, что перед ним хук, и проверяет его, включаяexhaustive-deps; - изоляция состояния: хук переиспользует логику, а не данные. Каждый компонент, вызвавший
useFetch(url), получает свойuseStateи свой эффект. Общие данные даёт контекст или внешний стор; - очистка: эффект возвращает функцию отписки. Для запроса это
AbortControllerиcontroller.abort()в cleanup, иначе ответ на старыйurlможет прийти позже нового и перезаписать данные; - зависимости: объект или функция, переданные в хук аргументом, создаются заново на каждом рендере и перезапускают эффект. Помогают
useMemo/useCallbackу вызывающего, передача примитивов илиuseEffectEventдля логики, которая должна видеть свежие пропсы, но не перезапускать эффект; - StrictMode: в разработке React монтирует, размонтирует и снова монтирует компонент, эффект срабатывает дважды. Это проверка, что cleanup написан.
Хорошо добавить, что для загрузки данных в реальном проекте обычно берут TanStack Query, SWR или загрузку на уровне фреймворка: кэш, повторы и дедупликация в самописном useFetch быстро разрастаются.
Где спотыкаются
Думают, что хук даёт общее состояние между компонентами, и удивляются двум одинаковым запросам с двух экранов.
Делают колбэк эффекта асинхронным: useEffect(async () => ...). Он возвращает промис вместо функции очистки, и отмены нет. Асинхронную функцию объявляют внутри эффекта и вызывают.
Отключают линтер на массиве зависимостей, чтобы убрать бесконечный цикл, и получают эффект, который работает со старыми значениями пропсов.