PassFront
  1. PassFront
  2. База знаний
  3. Хуки

Какие особенности зависимостей useMemo важно учитывать на практике и почему?

Хуки

Зависимости useMemo решают, когда пересчитывать закешированное значение. Особенности те же, что у остальных хуков, но последствия ошибок специфичны.

Сравнение поверхностное (Object.is)

Примитивы — по значению; объекты, массивы, функции — по ссылке. Отсюда:

const filters = { status };                                    // новая ссылка
const rows = useMemo(() => filter(data, filters), [data, filters]); // пересчёт всегда

Правильно — зависеть от примитивов ([data, status]) или стабилизировать объект выше.

Полнота: иначе устаревшее значение

Пропущенная зависимость даёт «застывший» результат: список не перефильтруется при смене критерия. Это баг корректности, а не производительности — опаснее лишнего пересчёта.

Мутации невидимы

data.push(x) не меняет ссылку — useMemo вернёт старый кеш. Обновления должны быть иммутабельными, иначе мемоизация «врёт».

useMemo — подсказка, не гарантия

React вправе выбросить кеш (документировано). Нельзя строить на useMemo логику «выполнится ровно один раз»: инициализация синглтонов — useRef или ленивый useState. Побочные эффекты в фабрике недопустимы: она вызывается во время рендера.

Стоимость самих зависимостей

Сравнение deps и хранение значения не бесплатны. Для дешёвых вычислений useMemo вреден: код сложнее, выигрыша нет. Смысл появляется при тяжёлых вычислениях или когда нужна стабильная ссылка (props memo-детей, deps эффектов).

Коротко для собеседования

Deps useMemo сравниваются по Object.is: объекты/функции — по ссылке (нужны примитивы или стабилизация), мутации не видны (только иммутабельность), список должен быть полным (иначе устаревшее значение). useMemo — подсказка, а не гарантия: без побочных эффектов и не для «выполнить один раз».

Другие вопросы раздела