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

Какие параметры есть у Memo?

2.0 Middle🔥 191 комментариев
#Soft Skills и рабочие процессы

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

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

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

Параметры функции memo в React

Функция React.memo принимает два параметра, которые позволяют тонко настраивать процесс мемоизации компонентов. Давайте рассмотрим их подробно.

1. Component (обязательный параметр)

Это сам React-компонент, который вы хотите мемоизировать. Обычно это функциональный компонент, но memo также работает с компонентами, созданными с помощью React.forwardRef.

// Базовый пример
const MyComponent = (props) => {
  return <div>{props.value}</div>;
};

const MemoizedComponent = React.memo(MyComponent);

2. arePropsEqual (опциональный параметр)

Это функция сравнения пропсов, которая позволяет кастомизировать логику определения, изменились ли пропсы. Если функция не передана, React использует поверхностное сравнение (shallow comparison) по умолчанию.

// Типизация TypeScript для второго параметра
type Comparator = (
  prevProps: Readonly<P>,
  nextProps: Readonly<P>
) => boolean;

Как работает функция сравнения:

  • Возвращает true, если пропсы считаются равными и компонент НЕ должен перерендериваться
  • Возвращает false, если пропсы разные и компонент ДОЛЖЕН перерендериться
  • По умолчанию React сравнивает каждый ключ пропсов через Object.is()

Пример с кастомной функцией сравнения

const UserProfile = ({ user, settings }) => {
  console.log('UserProfile render');
  return (
    <div>
      <h2>{user.name}</h2>
      <p>Theme: {settings.theme}</p>
    </div>
  );
};

// Кастомная функция сравнения
const arePropsEqual = (prevProps, nextProps) => {
  // Сравниваем только важные поля
  return (
    prevProps.user.id === nextProps.user.id &&
    prevProps.settings.theme === nextProps.settings.theme
  );
};

const MemoizedUserProfile = React.memo(UserProfile, arePropsEqual);

// Использование
const App = () => {
  const [user, setUser] = useState({ id: 1, name: 'Alex' });
  const [settings, setSettings] = useState({ theme: 'dark', language: 'en' });
  
  // Компонент перерендерится только при изменении user.id или settings.theme
  return <MemoizedUserProfile user={user} settings={settings} />;
};

Важные нюансы использования второго параметра

  1. Оптимизация с осторожностью: Кастомная функция сравнения может нарушить работу компонента, если вы забудете сравнить важные пропсы.

  2. Неглубокое сравнение сложных объектов:

// Проблема: объекты создаются заново при каждом рендере
const arePropsEqual = (prevProps, nextProps) => {
  // ❌ Не сработает, так как onClick - новая функция каждый раз
  return prevProps.onClick === nextProps.onClick;
};

// Решение: использовать useCallback для функций
const handleClick = useCallback(() => {
  // логика
}, [dependencies]);
  1. Игнорирование некоторых пропсов:
const arePropsEqual = (prevProps, nextProps) => {
  // Игнорируем пропс `timestamp`, который меняется каждый раз
  const { timestamp: prevTimestamp, ...prevRest } = prevProps;
  const { timestamp: nextTimestamp, ...nextRest } = nextProps;
  
  return shallowCompare(prevRest, nextRest);
};

Практические рекомендации

  • Используйте по умолчанию: В большинстве случаев достаточно поведения по умолчанию с поверхностным сравнением
  • Профилируйте перед оптимизацией: Не добавляйте arePropsEqual без необходимости - сначала убедитесь, что ререндеры действительно являются проблемой
  • Избегайте преждевременной оптимизации: React.memo не бесплатен - сравнение пропсов имеет свою стоимость
  • Комбинируйте с другими оптимизациями:
    const MemoizedComponent = React.memo(MyComponent);
    
    // Используйте вместе с useMemo и useCallback
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
    

Когда НЕ использовать кастомную функцию сравнения

  1. Компоненты с детьми (children): children обычно создаются заново при каждом рендере
  2. Часто меняющиеся пропсы: Если пропсы меняются чаще, чем происходит ререндер, мемоизация бессмысленна
  3. Простые компоненты: Для компонентов с легким рендером затраты на сравнение могут превысить выгоду

Важно помнить, что React.memo сравнивает только пропсы. Если компонент использует контекст (Context) или состояние (useState, useReducer), он все равно будет перерендериваться при их изменении, независимо от пропсов.