Supercharging your React projects with Memoization

useMemo and useCallback are React hooks for memoization. Think of memoization as caching a value so that it does not need to be recalculated. This improves performance. The main difference between useMemo and useCallback is that useCallback returns a m…


This content originally appeared on DEV Community and was authored by Paul-Simon Emechebe

useMemo and useCallback are React hooks for memoization. Think of memoization as caching a value so that it does not need to be recalculated. This improves performance. The main difference between useMemo and useCallback is that useCallback returns a memoized function (which just really means a 'cached function') and useMemo returns a memoized value. Let's go through these hooks together.

Let's start with useMemo

Using useMemo

One reason to use useMemo is to prevent an expensive function from re-rendering unless one of its dependencies update.

Problem

In this example, we have an expensive function that runs on every render.

When changing the count or adding a todo, you will notice a delay in execution.

import { useState } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const calculation = expensiveCalculation(count);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {calculation}
      </div>
    </div>
  );
};

const expensiveCalculation = (num) => {
  console.log("Calculating...");
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
};

ReactDOM.render(<App />, document.getElementById('root'));

Solution

To fix this performance issue, we have to find a way to prevent the rerender of the expensive function. To do this we'll have to memoize the expensive function. This is done by wrapping the expensive function call with useMemo.

The useMemo Hook accepts a second parameter to declare dependencies. The expensive function will only run when its dependencies have changed.

In the following example, the expensive function will only run when count is changed and not when todo's are added.

import { useState, useMemo } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const calculation = useMemo(() => expensiveCalculation(count), [count]);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {calculation}
      </div>
    </div>
  );
};

const expensiveCalculation = (num) => {
  console.log("Calculating...");
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
};

ReactDOM.render(<App />, document.getElementById('root'));

Let's look at useCallback!!!

Using useCallback

The main difference between useMemo and useCallback is that useCallback returns a memoized function (which just really means a 'cached function') and useMemo returns a memoized value.

( for the code example for useCallback, we'll use the exact example used for the useMemo but the expensive function would be in another component called ExpensiveCalc.js.)


import { useState } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);

  const increment = () => {
    setCount((c) => c + 1);
  };

  const expensiveCalculation = useCallback((num) => {
  console.log("Calculating...");
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
  }, [count]);  

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        <ExpensiveCalc count={count} increment={increment}/>
      </div>
    </div>
  );
};




ReactDOM.render(<App />, document.getElementById('root'));


ExpensiveCalc.js

import { memo } from "react";

const ExpensiveCalc = ({ count, increment }) => {
  console.log("child render");
  return (
    <>
      <h2>Count</h2>
      Count: {count}
      <button onClick={increment}>+</button>
    </>
  );
};

export default memo(ExpensiveCalc); //memo will cause React to skip rendering a component if its props have not changed.


This content originally appeared on DEV Community and was authored by Paul-Simon Emechebe


Print Share Comment Cite Upload Translate Updates
APA

Paul-Simon Emechebe | Sciencx (2022-07-04T03:10:38+00:00) Supercharging your React projects with Memoization. Retrieved from https://www.scien.cx/2022/07/04/supercharging-your-react-projects-with-memoization/

MLA
" » Supercharging your React projects with Memoization." Paul-Simon Emechebe | Sciencx - Monday July 4, 2022, https://www.scien.cx/2022/07/04/supercharging-your-react-projects-with-memoization/
HARVARD
Paul-Simon Emechebe | Sciencx Monday July 4, 2022 » Supercharging your React projects with Memoization., viewed ,<https://www.scien.cx/2022/07/04/supercharging-your-react-projects-with-memoization/>
VANCOUVER
Paul-Simon Emechebe | Sciencx - » Supercharging your React projects with Memoization. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/07/04/supercharging-your-react-projects-with-memoization/
CHICAGO
" » Supercharging your React projects with Memoization." Paul-Simon Emechebe | Sciencx - Accessed . https://www.scien.cx/2022/07/04/supercharging-your-react-projects-with-memoization/
IEEE
" » Supercharging your React projects with Memoization." Paul-Simon Emechebe | Sciencx [Online]. Available: https://www.scien.cx/2022/07/04/supercharging-your-react-projects-with-memoization/. [Accessed: ]
rf:citation
» Supercharging your React projects with Memoization | Paul-Simon Emechebe | Sciencx | https://www.scien.cx/2022/07/04/supercharging-your-react-projects-with-memoization/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.