← Назад к вопросам

Как работает UseMemo?

1.0 Junior🔥 251 комментариев
#React#Оптимизация и производительность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает useMemo?

useMemo — это React хук, который кэширует и мемоизирует результат дорогостоящего вычисления и возвращает его только если зависимости изменились. Это оптимизационный хук, который помогает избежать ненужных пересчётов в компонентах и значительно улучшает производительность приложения.

Синтаксис и базовое использование

const memoizedValue = useMemo(() => {
  return computeExpensiveValue(a, b);
}, [a, b]);

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

  • Первый рендер: computeExpensiveValue выполняется, результат сохраняется
  • Второй рендер (a, b не изменились): возвращает сохранённый результат
  • Третий рендер (a изменился): выполняется вычисление заново

Пример: дорогостоящее вычисление

import { useMemo, useState } from "react";

function OptimizedComponent() {
  const [count, setCount] = useState(0);
  
  const expensiveResult = useMemo(() => {
    return Array(1000000)
      .fill(0)
      .reduce((sum, _, i) => sum + i, 0);
  }, []);
  
  return (
    <div>
      <p>Результат: {expensiveResult}</p>
      <button onClick={() => setCount(count + 1)}>
        Клик: {count}
      </button>
    </div>
  );
}

Практический пример: фильтрация списка

function UserList({ users, searchQuery }) {
  const filteredUsers = useMemo(() => {
    return users.filter(user =>
      user.name.toLowerCase().includes(searchQuery.toLowerCase())
    );
  }, [users, searchQuery]);
  
  return (
    <ul>
      {filteredUsers.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Работа с зависимостями

Пустой массив — один раз вычисляет при монтировании:

const value = useMemo(() => {
  return expensiveComputation();
}, []);

Массив с зависимостями — вычисляет при изменении:

const value = useMemo(() => {
  return computeResult(count, name);
}, [count, name]);

Сравнение с useCallback

  • useMemo кэширует ЗНАЧЕНИЕ (результат вычисления)
  • useCallback кэширует ФУНКЦИЮ
const memoizedValue = useMemo(() => ({ id: 1 }), []);
const memoizedFunc = useCallback(() => {}, []);

Оптимизация дочерних компонентов

function Parent() {
  const userConfig = useMemo(() => ({
    theme: "dark",
    fontSize: 16
  }), []);
  
  return <Child config={userConfig} />;
}

const Child = React.memo(({ config }) => {
  return <div>Theme: {config.theme}</div>;
});

Один и тот же объект — дочерний не перерендерится.

Реальный пример: обработка таблицы

function DataTable({ data, sortBy, filterQuery }) {
  const processedData = useMemo(() => {
    let result = [...data];
    
    if (filterQuery) {
      result = result.filter(item =>
        item.name.toLowerCase().includes(filterQuery.toLowerCase())
      );
    }
    
    if (sortBy) {
      result.sort((a, b) => {
        return a[sortBy] > b[sortBy] ? 1 : -1;
      });
    }
    
    return result;
  }, [data, sortBy, filterQuery]);
  
  return (
    <table>
      <tbody>
        {processedData.map(item => (
          <tr key={item.id}>
            <td>{item.name}</td>
            <td>{item.value}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Когда использовать useMemo

ИСПОЛЬЗУЙ когда:

  • Дорогостоящие вычисления (> 1ms)
  • Результат передаётся в React.memo компонент
  • Фильтрация/сортировка больших массивов
  • Создание объектов для зависимостей дочерних компонентов

НЕ ИСПОЛЬЗУЙ когда:

  • Простые вычисления (count * 2)
  • Простые значения (строки, числа)
  • Нет реальной необходимости в оптимизации

Частые ошибки

Ошибка: забыли добавить зависимость

const result = useMemo(() => {
  return compute(count);
}, []); // count используется, но не в зависимостях!

Испраляю:

const result = useMemo(() => {
  return compute(count);
}, [count]);

Ошибка: функция в зависимостях

const value = useMemo(() => {
  return compute();
}, [() => {}]); // НОВАЯ функция каждый рендер!

Исправляю с useCallback:

const callback = useCallback(() => {}, []);
const value = useMemo(() => {
  return compute();
}, [callback]);

Лучшие практики

  1. Всегда используй правильные зависимости — eslint поможет
  2. Не оптимизируй прежде, чем измеришь — используй React DevTools Profiler
  3. Не переусложняй — useMemo добавляет память и сложность
  4. Используй для реально дорогих операций — вычисления, большие преобразования

useMemo — мощный инструмент для оптимизации React приложений, но использовать его нужно осознанно. Преждевременная оптимизация — корень всех зол!