DEV Community

Shailesh Kumar
Shailesh Kumar

Posted on

React Memo, useMemo, useCallback - Optimize your performance

Hello everyone!
In this blog we talk about how to optimize your react project.

In react there is a hook React.memo for optimizing the performance , and there is a React.useMemo also for optimizing the performance , another one is React.useCallback also for optimizing performance. so you are confused 😑 which one to used ?
let's dive in to the examples to understand you perfectly.

Scenario where need to optimize

In the above example there is component named as Child
and there is a counter state in parent/app.js. When you increment the counter the Child component also will be re-rendered (You can see the console after each click on the button)
while there is no state change in the child element ,then component will be re-rendered.

What is the solution for stop un-usual re-rendering ?

There is a concept called Memoization.
Let's see the definition of memoization

What is memoization ?

Memoization is an optimization technique that makes applications more efficient and hence faster🚀. It does this by storing computation results in cache, and retrieving that same information from the cache the next time it's needed instead of computing it again.

  • A memoized function remembers the result of an output for a given set of inputs. It means when you give it set of inputs it remembers those inputs and also output associative with it. Whenever passing a set of input to the memoized function first it check in the cached memory whether the set of inputs is available or not, if they have its give you computed value from the cached memory.

  • In React, we can memoized components (where the inputs are props) or functions.

Let's memoize our previous example:
We use React Memo for optimize this component example.

You can now check the console only first time render the child component after using React Memo.

What is Callback ?

MDN definition

A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.

Let's add an input field to the above example and pass props to child component function(setCounter) in which increase the counter value by calling this function.

In above codeSandBox example if we type in the input field then child component get re-rendered(You can see console), while there is no props pass to the Child component which is related to state Input text field. Then why this happening ?🤔

The child component get re-render because when the parent component render in each time the inline function which is pass in the child component is redefining the function calls another function which is called setCounter.

// passing function to the component
<Child updateCounter={() => setCounter((counter) => counter + 1)} />
Enter fullscreen mode Exit fullscreen mode

Now, we want to pass callback function with memoize, so React Memo working properly. We use useCallback to memoize the callback functions. Let's code and look how can we use useCallback hook.


export default function App() {
// ...
const updateCounterFromChild = useCallback(() => setCounter(counter + 1), [
    counter
  ]);

return (
// Some Jsx returns
<Child updateCounter={updateCounterFromChild} />
 )
}
Enter fullscreen mode Exit fullscreen mode

In useCallback({},[]) there is a dependency array list and we add dependency counter because the updateCounterFromChild function redefined only when the counter state is changed.

What is useMemo ?

Definition by ⚛️reacts.org:

useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.

Let's understand with the above statement they said avoid expensive calculations on every render.
Image description

In above example you can notice that there is very expensive calculation will be done as below you can see.

(function () {
    console.log("Expensive calucation to be started...");
    let tempNumber = 0;
    for (let i = 0; i < 500_000_000; i++) {
      tempNumber++;
    }
  })();
Enter fullscreen mode Exit fullscreen mode

In every click there is an delay for render the state of counter, because every click IIFE is called and doing expensive calculations. we don't want to re-rendered IIFE because every render we get same value from the previous render and this reason memoization comes.

We do two types of memoization in single example:

  1. Don't calculate expensive calculation in each render.
  2. I want to we update only Second counter in above example.

useMemo vs useEffect

If you think we can do second part of the above statement with the help of useEffect then you can't do with this because, useEffect work for whole component of the app but useMemo can work for some part of the component. let's see with the code how useMemo work for some part of the HTML code.

As you can see the above codeSandBox output the re-render after every click becomes smooth and there is no console of the IIFE.
First counter not get affected by the Increment click. If you want to update also the state of first counter then you pass dependencies array counter to the useMemo.

Thanks for reading this blog with the patience 😊, and i suppose to be that you will get learn something from this blog.
Give your love💖 and feedback💬 to this blog.

Top comments (0)