DEV Community 👩‍💻👨‍💻

Cover image for Когда нужен React.memo?
jennypollard
jennypollard

Posted on • Updated on

Когда нужен React.memo?

Когда нужен React.memo?

Компонент обновляется (перерисовывается), когда меняется его состояние. Когда обновляется компонент, обновляются все его дочерние компоненты и рекурсивно дочерние компоненты дочерних компонентов.

Компонент может иметь глубокую вложенность дочерних компонентов:

const C = () => <div />;
const B = () => <C />
const A = () => <B />;

const App = () => {
    return <A />;
}
Enter fullscreen mode Exit fullscreen mode

В примере выше, при обновлении компонента App произойдет обновление всех вложенных компонентов: A, B и C.

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

export function memo(type, compare) {
  const elementType = {
    $$typeof: REACT_MEMO_TYPE,
    type,
    compare: compare === undefined ? null : compare,
  };

  return elementType;
}
Enter fullscreen mode Exit fullscreen mode

При обновлении компонентов, React распознает мемо и вызывает функцию compare чтобы определить изменились ли пропсы, если нет — можно пропустить обновление:

const prevProps = currentChild.memoizedProps;
// Default to shallow comparison
let compare = Component.compare;
compare = compare !== null ? compare : shallowEqual;
if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
  return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
}
Enter fullscreen mode Exit fullscreen mode

Возвращаясь к первому примеру, обернем компонент A в мемо:

const C = () => <div />;
const B = () => <C />
const A = React.memo(() => <B />);

const App = () => {
    return <A />;
}
Enter fullscreen mode Exit fullscreen mode

Теперь, при обновлении App, компонент A и его вложенные компоненты обновляться не будут, так как их пропсы не изменяются.

Использование мемо даст результат, если:

  • компонент перерисовывается (обновляется) часто с одними и теми же пропсами.
  • обновление компонента дорогое, например, когда у компонента большая вложенность дочерних компонентов.

Credits: foto by Oskar Yildiz https://unsplash.com/photos/gy08FXeM2L4

Top comments (0)

Let's Get Hacking

Join the DEV x Linode Hackathon 2022 and use your ingenuity and creativity to build using Linode.

Join the Hackathon <-