> Можно ли использовать useEffect в кастомном хуке (React)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Консорциум кодекс

Стек: React

> Пример ответа

Короткий ответ

Да, можно и часто нужно. Кастомные хуки - это обычные функции, которые могут вызывать любые встроенные хуки React, включая useEffect. Это один из основных паттернов для инкапсуляции логики с побочными эффектами (сайд-эффектами), таких как подписки, таймеры, запросы к API или работа с DOM. Главное - соблюдать правила хуков: вызывать useEffect только на верхнем уровне кастомного хука и не внутри условий или циклов.

Подробное объяснение

Кастомный хук - это JavaScript-функция, имя которой начинается с use, и она может вызывать другие хуки React. Использование useEffect внутри кастомного хука - это стандартный способ абстрагировать повторяющуюся логику, связанную с жизненным циклом компонента. Например, вы можете создать хук useWindowSize, который подписывается на resize и обновляет состояние - внутри него будет useEffect для добавления и удаления слушателя.

Важно понимать, что кастомный хук не создаёт собственного жизненного цикла - он разделяет жизненный цикл того компонента, в котором вызывается. Поэтому useEffect внутри кастомного хука ведёт себя точно так же, как если бы он был написан напрямую в компоненте: он выполняется после рендера, поддерживает массив зависимостей и функцию очистки.

Это даёт мощный механизм композиции: вы можете комбинировать несколько кастомных хуков с useEffect внутри одного компонента, и каждый будет работать независимо. Также это улучшает тестируемость и переиспользование кода.

На практике

При разработке на React старшего уровня вы будете постоянно использовать этот паттерн. Типичные примеры: хук для работы с WebSocket (useWebSocket), хук для Intersection Observer (useInfiniteScroll), хук для дебаунса (useDebounce) или хук для анимаций. Главное - следить за тем, чтобы зависимости в useEffect были корректно указаны, иначе можно получить бесконечные ререндеры или утечки памяти.

Также стоит помнить, что если кастомный хук использует useEffect, то он должен вызываться только внутри React-компонента или другого кастомного хука - это правило хуков. Нарушение приведёт к ошибке.

Пример кода

JSX
import { useState, useEffect } from 'react';
function useWindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
useEffect(() => {
const handleResize = () => {
setSize({
width: window.innerWidth,
height: window.innerHeight
});
};
window.addEventListener('resize', handleResize);
// Функция очистки - удаляем слушатель при размонтировании
return () => window.removeEventListener('resize', handleResize);
}, []); // Пустой массив - эффект выполняется только при монтировании
return size;
}
// Использование в компоненте
function App() {
const { width, height } = useWindowSize();
return <div>Window: {width} x {height}</div>;
}

Как отвечать на собеседовании

Начните с прямого утвердительного ответа. Затем объясните, что это не только возможно, но и является рекомендуемым паттерном для инкапсуляции логики с побочными эффектами. Приведите пример из практики - например, хук для подписки на внешний источник данных. Подчеркните, что кастомный хук с useEffect подчиняется тем же правилам, что и любой другой хук: он должен вызываться на верхнем уровне, не внутри условий, и его зависимости нужно правильно указывать. Если спросят про очистку - объясните, что функция очистки в useEffect внутри кастомного хука работает так же, как и в компоненте.

Что проверяет интервьюер

Интервьюер проверяет понимание того, что кастомные хуки - это не магия, а просто функции, которые могут использовать любые встроенные хуки. Также оценивается знание правил хуков и умение проектировать переиспользуемую логику. Важно показать, что вы понимаете разницу между чистыми функциями и хуками с эффектами, и умеете правильно управлять жизненным циклом через зависимости и очистку.

Типичные ошибки

  • Забывают указать массив зависимостей, что приводит к бесконечным вызовам эффекта.
  • Не возвращают функцию очистки, из-за чего возникают утечки памяти (например, слушатели событий остаются висеть).
  • Пытаются использовать useEffect внутри условного оператора или цикла внутри кастомного хука - это нарушает правила хуков.
  • Создают кастомный хук, который вызывает useEffect, но сам хук вызывается не из React-компонента - это приведёт к ошибке.
  • Излишне усложняют хук, пытаясь сделать его универсальным, вместо того чтобы решить конкретную задачу.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью