useCallback

Тема дорожной карты · React

useCallback — это React-хук оптимизации производительности, мемоизирующий ссылку на функцию и возвращающий один и тот же объект функции между рендерами до тех пор, пока его массив зависимостей не изменится, — что предотвращает ненужные перерендеры дочерних компонентов, получающих функцию в виде пропса. Хук принимает два аргумента: функцию-коллбэк и массив зависимостей — аналогично useMemo, но специализированный для функций, а не вычисляемых значений. useCallback особенно ценен при передаче коллбэков дочерним компонентам, обёрнутым в React.memo, поскольку без мемоизации при каждом рендере родителя создаётся новая ссылка на функцию, заставляя поверхностное сравнение React.memo провалиться и запуская ненужный перерендер дочернего компонента. В TypeScript useCallback автоматически выводит тип возврата и типы параметров из коллбэка, но при недостаточности вывода можно указать явные обобщённые типы. Чрезмерное использование useCallback для функций, которые не передаются как пропсы или не используются в массивах зависимостей, добавляет накладные расходы без пользы, поэтому его следует применять избирательно как часть обоснованной измерениями стратегии оптимизации производительности React совместно с useMemo и React.memo.

Как это работает

useCallback — обычные JavaScript-функции, чьё имя начинается с use. Они подчиняются тем же правилам, что и встроенные хуки (вызов на верхнем уровне, никогда внутри условий/циклов) и могут звать другие хуки. Они упаковывают переиспользуемую stateful-логику — useFetch(url), useDebounce(value, ms), useLocalStorage(key, init) — и возвращают значения, коллбэки или и то и другое. useMemo(compute, deps) и useCallback(fn, deps) кешируют значения/коллбэки между рендерами, чтобы избежать лишних пересчётов или ререндера детей.

Когда применять

Выносите кастомный хук, когда один и тот же танец useState+useEffect появляется в двух компонентах — особенно если есть setup + teardown. useMemo — только когда профайл показывает дорогой пересчёт (иначе оверхед учёта превышает экономию). useCallback — в основном для стабилизации идентичности коллбэка для мемоизированных детей; для хендлеров, не выходящих за компонент, обычные функции ок.

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

Ловушки useCallback: вынос хука для короткого кода, исполняющегося раз (premature abstraction); функция со state, названная useX лишь по конвенции, но не следующая правилам хуков; useMemo/useCallback повсюду "для производительности" (каждый добавляет memory + comparison overhead); эффекты внутри условных веток кастомного хука (ломает порядок хуков). Профилируйте перед оптимизацией; пишите хук, когда есть 2+ места вызова.

Связанные понятия

Полезные ресурсы