UseMemo в React: кеширование вычисления и проверка зависимостей

UseMemo в React: кеширование вычисления и проверка зависимостей
Содержание статьи

useMemo() позволяет повторно использовать результат вычисления между рендерами, если зависимости не изменились. Он полезен при подтверждённо затратной работе, но не исправляет ошибочную логику. Компонент должен оставаться правильным, даже если вычисление будет выполнено заново.

Фильтрация списка по запросу

Пусть компонент получает массив задач и поисковую строку. Каждый элемент имеет уникальный id и строковое поле title. Фильтрация создаёт новый массив и не меняет входные данные.

import { useMemo } from "react";

export function TaskList({ items, query }) {
  const visible = useMemo(() => {
    const normalized = query.trim().toLowerCase();
    return items.filter(item =>
      item.title.toLowerCase().includes(normalized)
    );
  }, [items, query]);

  return (
    <ul>
      {visible.map(item => <li key={item.id}>{item.title}</li>)}
    </ul>
  );
}

При первом рендере React вычислит visible. На следующих рендерах он сравнит каждую зависимость через Object.is. Если ссылки на items и значение query прежние, сохранённый результат можно использовать снова. Изменение запроса или массива вызывает новое вычисление.

Зависимости определяются кодом

В функции используются items и query, поэтому оба значения входят в массив зависимостей. Пустой массив здесь не означает «оптимизировать сильнее»: он оставит результат связанным с первоначальными данными. Удалять зависимость ради исчезновения повторных вычислений нельзя.

Обратная ситуация: родитель при каждом рендере создаёт новый массив items с тем же содержимым. Ссылка будет новой, и кеш не даст ожидаемой экономии. Сначала проверьте источник изменений. Не нужно оборачивать каждую переменную в дополнительный хук без измерений.

Почему нельзя менять исходный массив

Если добавить задачу через items.push() и сохранить прежнюю ссылку, сравнение зависимости не отражает изменение содержимого. В React обновляйте состояние новым массивом и сохраняйте чистоту функции вычисления. Внутри useMemo не следует отправлять запросы, записывать данные или менять чужие объекты: это работа другого рода.

Хук вызывают на верхнем уровне компонента, без условий и циклов. В режиме Strict Mode при разработке React может вызвать функцию вычисления дважды для выявления нечистой логики. Это не означает две пользовательские операции в production. Чистая фильтрация выдерживает повторное выполнение без побочных эффектов.

Как решить, нужна ли мемоизация

Сначала измерьте фильтрацию на характерном размере данных и проверьте, повторяется ли она при нерелевантных изменениях. Затем сравните поведение с мемоизацией. У небольшого списка эффект может быть незаметным. React также вправе отбросить кеш, поэтому использовать его вместо состояния или гарантированного хранилища нельзя.

В функциональных проверках смените query, передайте новый items, проверьте пустой запрос и отсутствие совпадений. Правильность результата должна сохраняться и при обычном вычислении без useMemo.

Закрепить работу с рендерами можно на курсе React. Для разбора реального профиля компонента на Mentoring.digital доступны наставники по React: полезнее показать измерение и поток данных, чем только число использованных хуков.

Похожие статьи по данной теме