В чем разница между useMemo и React.memo

Ответ

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

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

React.memo — это HOC (Higher-Order Component), который мемоизирует сам компонент, предотвращая его перерендер, если пропсы не изменились. Оптимизирует рендер дочерних компонентов.

const MemoizedComponent = React.memo(MyComponent);

Ключевые отличия:

  • useMemo кэширует значение, React.memo — компонент.
  • useMemo работает внутри компонента, React.memo оборачивает компонент.
  • useMemo зависит от зависимостей, React.memo — от пропсов.

Ответ 18+ 🔞

А, ну это классика, блядь! Вечная путаница у новичков, аж волнение ебать чувствую, когда её объясняю. Слушай сюда, разжую как для мартышлюшки.

Представь, что твой компонент — это такой вечно голодный чувак на кухне. Каждый раз, когда ему надо поесть (отрендериться), он готовит себе сложный хуёвый салат computeExpensiveValue(a, b). Режет там огурцы, перцы, всё это дело. Каждый рендер — новая порция, сил нет, заебался уже.

Так вот useMemo — это как контейнер «Тупера», сука. Ты один раз приготовил этот салат, положил его в контейнер и говоришь: «Слушай, организм, пока ингредиенты [a, b] не поменялись — не еби мозг, доставай из холодильника готовое». Не готовишь заново, экономишь силы.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
// Пока a и b те же — не трогай computeExpensiveValue, бери из кэша, блядь.

А теперь другая история. React.memo — это вообще про другого чувака. Допустим, у тебя есть компонент-ребёнок MyComponent. И его родитель каждый раз, когда чихнёт, перерисовывает всё, включая этого ребёнка. А ребёнок-то, сука, не менялся! На него пришли те же самые пропсы.

React.memo — это как поставить на вход к этому ребёнку охранника-бульдога. Охранник смотрит на пропсы, которые несут ребёнку: «А, хуй с горы, те же самые, что и в прошлый раз? Иди нахуй, не пущаю, нечего тут перерисовываться!». Компонент остаётся старым, рендер не происходит. Экономит ресурсы на отрисовке целого куска дерева.

const MemoizedComponent = React.memo(MyComponent);
// Не трогай MyComponent, если пропсы не изменились, ёпта!

Короче, отличия, чтобы вротберунчик не свернулся:

  • useMemo — кэширует ЗНАЧЕНИЕ (результат тяжёлой функции) ВНУТРИ компонента. Это про то, что считать.
  • React.memo — кэширует ЦЕЛЫЙ КОМПОНЕНТ (его вывод). Это про то, кого рисовать. Обёртка снаружи.

Используй useMemo, когда боишься за сложные вычисления в теле компонента. Используй React.memo, когда боишься, что родительский компонент без нужды дёргает своих детей. Вот и вся магия, никакого ёперного театра.