Feature Image

Introduction

In React, memoization refers to the practice of optimizing the performance of a component by avoiding unnecessary re-renders. This can be achieved in several ways, including using the React.memo higher-order component or the useMemo hook.

Problem statement

If you're not using React.memo or useMemo in a React app, it's possible that your components may be re-rendering unnecessarily, which can impact the performance of your app.

Here's an example of how this might happen:

function ExpensiveComponent(props) {
  const [count, setCount] = useState(0)

  // This function is expensive to calculate
  function calculateValue() {
    console.log('Calculating value...')
    let result = 0
    for (let i = 0; i < 100000000; i++) {
      result += i
    }
    return result
  }

  // The value is recalculated on each render
  const value = calculateValue()

  return (
    <div>
      <h1>{value}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}

export default ExpensiveComponent

In this example, the calculateValue function is expensive to calculate, and it is called on each render of the ExpensiveComponent. This means that the value will be recalculated each time the component is rendered, even if the value has not changed. This can lead to slower performance and unnecessary calculation.

Solution

To optimize the performance of this component, you could wrap the MyItem component with React.memo or use the useMemo hook inside the MyItem component to memoize the expensiveValue calculation. This would prevent the MyItem components from re-rendering unnecessarily and improve the overall performance of the app.

React.memo

The React.memo function is a higher-order component that wraps a component and only re-renders it if its props have changed. It's a way to optimize the performance of a component by preventing it from re-rendering unnecessarily.

Here's an example of how you might use React.memo to optimize the performance of a component:

import React, { useState } from 'react';

function ExpensiveComponent(props) {
  // component body
}

- export default ExpensiveComponent;
+ export default React.memo(ExpensiveComponent);

In this version, the ExpensiveComponent is wrapped in a call to React.memo. This will cause the component to only re-render when its props have changed, rather than on every update.

useMemo

The useMemo hook is similar to React.memo, but it's a function that's called inside a component rather than a component that wraps another component. It allows you to memoize a value that is expensive to compute. This means that the value will be computed only if one of its dependencies has changed, which can help to improve the performance of a component by avoiding expensive calculations on every render.

Here's an example of how you might use useMemo to optimize the performance of a component:


function ExpensiveComponent(props) {
  ...

- const value =  calculateValue();
+ const value = useMemo(() => calculateValue(), [count]);

  return (
  //jsx content
  );
}

export default ExpensiveComponent;

In this updated version of the component, the useMemo hook is used to memoize the value of calculateValue. The value is only recalculated when the count state variable changes, which means that it will not be unnecessarily recalculated on each render.