В чем разница между useEffect и useCallback?
Хуки
Хуки из разных категорий: useEffect выполняет побочные эффекты, useCallback мемоизирует функцию. Путают их из-за похожей сигнатуры (колбэк + массив зависимостей).
Суть каждого
// useEffect: ВЫПОЛНИТЬ код после рендера (при изменении deps)
useEffect(() => {
document.title = `Чат ${roomId}`;
const conn = connect(roomId);
return () => conn.close();
}, [roomId]);
// useCallback: НЕ выполнять, а ЗАПОМНИТЬ функцию (пока deps не изменились)
const handleSend = useCallback((text) => {
api.send(roomId, text);
}, [roomId]);Отличия
- Что делает с колбэком: useEffect вызывает его сам (после коммита); useCallback никогда не вызывает — только возвращает стабильную ссылку, вызовете вы.
- Возвращаемое значение: useEffect ничего не возвращает; useCallback возвращает функцию.
- Назначение: side-эффекты (запросы, подписки, DOM) против оптимизации (стабильные пропсы для React.memo, стабильные зависимости).
- Cleanup: у useEffect есть механизм очистки; у useCallback нет.
- Роль deps: у useEffect — «когда перезапустить эффект»; у useCallback — «когда пересоздать функцию».
Как они работают вместе
const loadPage = useCallback(() => fetchItems(page), [page]);
useEffect(() => {
loadPage(); // эффект перезапустится только при смене page
}, [loadPage]);Стабильная функция из useCallback становится «хорошей» зависимостью эффекта.
Коротко для собеседования
useEffect — выполнение побочных эффектов после рендера (с cleanup), useCallback — мемоизация ссылки на функцию без её вызова (для React.memo-детей и зависимостей других хуков). Общее — только синтаксис с deps; роли не пересекаются, но хуки часто работают в связке.