Вопрос нужен, чтобы оценить, понимает ли кандидат, что именно стабилизируют useMemo и useCallback, и когда это реально снижает ререндеры.
Мемоизация значений (useMemo) сохраняет результат вычисления, чтобы не пересчитывать его без нужды. Мемоизация функций (useCallback) сохраняет ссылку на функцию, чтобы она не создавалась заново. В React это важно из-за shallow сравнения props и зависимостей. Оба инструмента полезны, когда вычисления дорогие или когда ссылка влияет на ререндер дочерних компонентов.
React опирается на ссылочную идентичность: если объект/функция новая по ссылке, это считается изменением. Отсюда появляются лишние ререндеры и лишние пересчёты.
useMemo запоминает “значение”, обычно:
результат вычисления
объект/массив, который важно сохранить по ссылке
Когда полезно:
Дорогие вычисления
сортировка
фильтрация
агрегации
Стабилизация props
чтобы React.memo у ребёнка сработал
Пример:
const filtered = useMemo(() => {
return items.filter(x => x.includes(query))
}, [items, query])
useCallback запоминает “ссылку на функцию”.
Это важно, потому что:
функция, объявленная в компоненте, создаётся заново на каждый рендер
если её передать вниз как prop, React.memo увидит “props изменился”
Пример:
const onSelect = useCallback((id) => {
setSelectedId(id)
}, [])
useMemo возвращает значение
useCallback возвращает функцию
При этом по смыслу useCallback(fn, deps) эквивалентен:
useMemo(() => fn, deps)
Но useCallback читается проще, когда речь именно о функциях.
Мемоизация — это не бесплатная оптимизация.
Проблемы:
усложнение кода
риск ошибок с зависимостями
накладные расходы на сравнение deps
Поэтому применять стоит, когда есть понятная причина:
компонент реально дорогой
функция/объект реально ломает мемоизацию детей
вычисление реально тяжёлое
Если у вас есть ребёнок, обёрнутый в React.memo, и вы передаёте туда:
объект
массив
функцию
то без useMemo / useCallback часто получится, что ребёнок всё равно будет перерисовываться из-за новых ссылок.
Мемоизация значений снижает количество пересчётов и стабилизирует ссылки на данные, а мемоизация функций — стабилизирует ссылки на обработчики. Оба инструмента помогают React.memo и зависимости эффектов работать предсказуемо, но применять их нужно точечно.