React Grimoire
  • ⁉️Introduction
  • 🧑‍🎓🧑🎓 React Fundamentals
    • The Basic javascript "Hello world"
    • Basic view on React core API's
    • JSX
    • React Props and styling
    • Components
    • Handling Events With React
    • Form
    • Array and Lists
    • Class Component State
    • Class Component Life Cycle
    • PropTypes
  • 🪝React Hooks
    • Intro to hooks
    • useState
    • useEffect
    • useRef
    • useContext
    • useMemo
    • useCallback
    • useReducer
    • useLayoutEffect
    • useImperativeHandle
    • Hook flow
    • Custom hooks
      • useDebugValue
    • React 18 hooks
  • 📓React Guidelines
    • React Components Composition Guidelines
    • React hooks guidelines
    • The use of Memoization
    • Lifting State Up
  • 🔭Concepts
    • Advanced Patterns
      • Compound Components Pattern
      • Control Props Pattern
      • Props Getters Pattern
      • Custom hook pattern
      • Context Module
      • State Reducer
    • React Under the hood
      • 🏁What is "Rendering"?
      • 🏁React Lifecycle
      • 🏁Reconciliation & Virtual DOM in React
      • 🏁Fiber
    • ⏰Concepts to always have in mind
  • 🧩React ecosystem
    • Forms Tools
      • React Hook Form VS Formik
    • TypeScript
      • 🏁Conditional React props with TypeScript
    • 🏁Build tool choice for MVP projects
    • A CSS methodology comparison
      • 🏁Post CSS processor :Sass
      • 🏁CSS in js :Styled-components
      • 🏁Utility Classes: Tailwind
  • ⁉️Testing
    • In Progress
  • 🎭Performance
    • in Progress
  • 🚀Deployment
    • In Progress
  • 🖼️Design system
    • 🏁What's a design system anyway ?​?
  • 🔗Us-full links
    • Typescript and React basic tutorial
    • React-philosophies
    • React new doc
Powered by GitBook
On this page
  • Memoization
  • useMemo
  • Factorial example
  • Use memoization with care
  • References and articles :

Was this helpful?

Edit on GitHub
  1. React Hooks

useMemo

PrevioususeContextNextuseCallback

Last updated 3 years ago

Was this helpful?

As apps become larger and more complex, writing efficient React code is becoming more and more important than ever. Re-rendering large components is expensive, and giving the browser a significant amount of work through a single-page application (SPA) increases processing time and may drive away users.

A common concern among those who work with React js stands for performance. React is fantastic, and if used correctly, there should be no re-rendering issues when states change.

First, let's understand the concept of memoization and why we need it.

Memoization

In computing, memorization or memorization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

Memoization: a performance optimization technique which eliminates the need to recompute a value for a given input by storing the original computation and returning that stored value when the same input is provided. Caching is a form of memoization. Here's a simple implementation of memoization:

const values = {}
function addOne(num: number) {
  if (values[num] === undefined) {
    values[num] = num + 1 // <-- here's the computation
  }
  return values[num]
}

Understanding JavaScript equality check

Functions in JavaScript are first-class citizens, meaning that a function is a regular object. The function object can be returned by other functions, be compared, etc exactly like an object.

But if we have one function and run it twice setting it to two different variables and compare it (like below), this will return false and we have the same logic applied to objects

const sum =()=> {
  return (a, b) => a + b;
}

const sum1 = sum();
const sum2 = sum();
sum1(1, 2); // => 3
sum2(1, 2); // => 3

console.log(sum1 === sum2); // => false
console.log(sum1 === sum1); // => true

useMemo

The hook useMemo receives two parameters: a function that will compute and return a value and an array of dependencies (like useEffect).

During initial rendering, useMemo(compute, dependencies) invokes the compute function memorizes the calculation result, and returns it to the component.

If during next renderings the dependencies don't change, then useMemo() doesn't invoke compute but returns the memorized value.

But if dependencies change during re-rendering, then useMemo() invokes compute function memorizes the new value, and returns it.

If your computation callback uses props or state values, then be sure to indicate these values as dependencies:

This hook is normally used when we have some calculation based on a prop (like the example below) or when we want to memorize a component with the props sent.

import * as React from "react";

const Element = ({ random }: { random: number }) => {
  const memoized = useMemo(() => (random * 100) / 33, [random]);
  return <>{memoized}</>;
};

export const App =()=> {
  const randomNumber = 100390;

  return <AnotherComponent random={random} />;
}

Factorial example

Every time you change the input value, the factorial is calculated factorialOf(n) and 'factorialOf function has been called' is logged to console.

On the other side, each time you click Re-render button, inc state value is updated. Updating inc state value triggers <Factorial /> re-rendering. But, as a secondary effect, during re-rendering the factorial is recalculated again — 'factorialOf function has been called' is logged to console.

How can you memorize the factorial calculation when the component re-renders? Welcome useMemo() hook!

By using useMemo(() => factorialOf(number), [number]) instead of simple factorialOf(number), React memorizes the factorial calculation.

You can play with the example below and try the two scenarios with useMemo and without

When not to use it

Nothing is bulletproof in real life, so even those hooks that were made to improve performance in some cases will slow down your app.

Performance optimizations are not free. They ALWAYS come with a cost but do NOT always come with a benefit to offset that cost.

To have the memorization working React needs to deal with this data, calculate it and save it (deals with a garbage collector, etc). My opinion is that those hooks should only be used if:

  • You have some calculations that will be computationally expensive

  • When you need to compare it (like the case of passing a function down to a Child Component)

Use memoization with care

While useMemo() can improve the performance of the component, you have to make sure to profile the component with and without the hook. Only after that make the conclusion whether memoization worth it.

When memoization is used inappropriately, it could harm the performance.

References and articles :

🪝
Memoization and ReactMemoization and React
Hooks API Reference – React
JavaScript Function Memoization - In Lehman's Terms
When to useMemo and useCallbackkentcdodds
Explaining Value vs. Reference in JavascriptMedium
A Visual Guide to React Rendering - useMemo
MemoizationWikipedia
Logo
Logo
Logo
Logo
Logo
Logo