> Какова стратегия использования React хуков и когда их применять (React)

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

Компании: Альфа-банк

Стек: React

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

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

Стратегия использования React хуков строится на принципах: один хук - одна ответственность, кастомные хуки для инкапсуляции логики, хуки вызываются только на верхнем уровне компонента. Применяем useState для локального состояния, useEffect для сайд-эффектов, useCallback/useMemo для оптимизации, useRef для ссылок на DOM или mutable значений. Кастомные хуки выносят повторяющуюся логику между компонентами.

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

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

  • Один хук - одна ответственность: каждый хук решает конкретную задачу. useState управляет локальным состоянием, useEffect выполняет сайд-эффекты (запросы, подписки, таймеры), useRef хранит mutable значения без ререндеров.
  • Кастомные хуки для абстракции: когда логика повторяется в нескольких компонентах, её выносят в кастомный хук. Например, useDebounce, useFetch, useLocalStorage.
  • Правила хуков: хуки вызываются только на верхнем уровне компонента или кастомного хука, не внутри условий, циклов или вложенных функций. Это гарантирует стабильный порядок вызовов между рендерами.
  • Оптимизация с useCallback и useMemo: эти хуки предотвращают лишние ререндеры дочерних компонентов, мемоизируя функции и вычисления. Однако их стоит применять только при реальной проблеме производительности, а не по умолчанию.
  • useReducer для сложного состояния: когда состояние имеет несколько полей или сложную логику обновления, useReducer даёт более предсказуемый паттерн, похожий на Redux.

Когда применять хуки:

  • useState - для любого локального состояния (инпуты, toggle, счётчики).
  • useEffect - для операций, которые должны происходить после рендера (fetch, подписки, обновление document.title).
  • useRef - для доступа к DOM-элементам, хранения предыдущих значений, таймеров.
  • useContext - для передачи глобальных данных без prop drilling (тема, аутентификация).
  • useCallback/useMemo - когда передаёте функции или объекты в дочерние компоненты, обёрнутые в React.memo.
  • Кастомные хуки - когда видите повторяющуюся логику с useState/useEffect в нескольких компонентах.

На практике

В реальных проектах стратегия выглядит так:

  1. Начинаем с простых useState и useEffect внутри компонента.
  2. Как только компонент разрастается, выносим связанную логику в кастомный хук.
  3. Для глобального состояния используем useContext или библиотеки вроде Zustand/Redux Toolkit.
  4. Оптимизацию (useCallback, useMemo) применяем только после профилирования и выявления узких мест.
  5. Избегаем избыточности: не создаём хук для одной строки кода, не оборачиваем всё в useMemo.

Типичный сценарий: форма с валидацией - используем useReducer для управления полями и ошибками, кастомный хук useForm для инкапсуляции логики, useEffect для отправки данных при сабмите.

Пример кода

JSX
// Кастомный хук для работы с localStorage
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});
const setValue = useCallback((value) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error(error);
}
}, [key, storedValue]);
return [storedValue, setValue];
}
// Использование в компоненте
function ThemeToggle() {
const [theme, setTheme] = useLocalStorage('theme', 'light');
const toggleTheme = useCallback(() => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
}, [setTheme]);
return (
<button onClick={toggleTheme}>
Current theme: {theme}
</button>
);
}

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

Начните с краткого определения стратегии, затем перечислите основные хуки и их назначение. Обязательно упомяните правила хуков и кастомные хуки как инструмент абстракции. Приведите пример из практики - как вы выносили логику в useDebounce или useFetch. Подчеркните, что оптимизация должна быть обоснованной, а не преждевременной. Если спросят про trade-off, скажите, что хуки упрощают тестирование и переиспользование, но требуют дисциплины в соблюдении правил.

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

  • Понимание принципов работы хуков и их ограничений.
  • Умение проектировать архитектуру с кастомными хуками.
  • Знание правил хуков и последствий их нарушения.
  • Способность отличать, когда нужен useEffect, а когда useRef или useCallback.
  • Опыт реального применения - не теоретические знания, а практические кейсы.

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

  • Вызов хуков внутри условий или циклов - нарушение правил, приводит к багам.
  • Злоупотребление useEffect - использование его для вычислений, которые можно сделать в рендере.
  • Избыточная мемоизация - оборачивание всего подряд в useCallback/useMemo без профилирования.
  • Игнорирование зависимостей в useEffect - пропуск важных переменных из массива зависимостей.
  • Создание кастомных хуков для слишком простой логики - усложнение без необходимости.
  • Забывание cleanup в useEffect - подписки, таймеры и event listeners не отписываются, вызывая утечки памяти.

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

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