React Hooks изменили способ написания компонентов. Но с ними приходит и новая категория ошибок.

useEffect: правила и ловушки

useEffect выполняется после рендера. Это не componentDidMount — он ведёт себя иначе.

// Проблема: бесконечный цикл
useEffect(() => {
  setCount(count + 1); // Изменяет count → триггерит ре-рендер → снова useEffect
}, [count]);

// Решение: функциональное обновление
useEffect(() => {
  setCount(prev => prev + 1);
}, []); // Только при монтировании

useCallback и useMemo: не оптимизируйте преждевременно

Главное правило: не используйте без профилирования.

// Не нужно мемоизировать примитивы
const value = useMemo(() => 42, []); // Бессмысленно

// Нужно: тяжёлые вычисления
const sortedList = useMemo(
  () => items.sort((a, b) => b.date - a.date),
  [items]
);

Пользовательские хуки

Главная мощь хуков — инкапсуляция логики:

function useLocalStorage<T>(key: string, initial: T) {
  const [value, setValue] = useState<T>(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initial;
  });

  const setStored = (newValue: T) => {
    setValue(newValue);
    localStorage.setItem(key, JSON.stringify(newValue));
  };

  return [value, setStored] as const;
}

Итог

React Hooks — мощный инструмент. Но мощь требует понимания. Читайте документацию React по правилам хуков, профилируйте перед мемоизацией, и не бойтесь пользовательских хуков для переиспользования логики.