DEV Community

Cover image for How to Use the useMemo and useCallback Hooks for Caching in React
Daniel Musembi
Daniel Musembi

Posted on

How to Use the useMemo and useCallback Hooks for Caching in React

INTRODUCTION

As your React skills grow, you'll start to care more and more about how well your app performs.

When it comes to optimizing React applications, caching is as important as it is with any other tool or programming technique.

In React, caching is most commonly referred to as memorization. In order to boost performance, it is employed to lessen the number of times a component is rendered as a result of state or prop changes.

Both useMemo and useCallback are available as caching APIs in React. The difference between useCallback and useMemo is that the former memoizes a function and the latter a value. When combined with the Context API, these two hooks can significantly boost productivity.

The following is a brief outline of the subjects that will be discussed in this article:

  • The default caching settings for React.

  • The useMemo hook.

  • The useCallback hook.

The default caching settings for React

To evaluate if a component needs to be re-rendered, React employs a "shallow comparison" method by default. This means that if a component's props or state haven't changed, React won't re-render its output because it will think that it hasn't changed.

However, optimizing complicated components that require sophisticated state management often necessitates going beyond the normal caching behavior's scope.

React provides the useMemo and useCallback hooks so that you can have a greater say over how your component caches and renders data.

useMemo hook for caching in React

If you need to do an expensive computation to retrieve a value and you want to be sure that it is only performed when absolutely necessary, useMemo is a valuable tool. If you use useMemo to memoize the value, you can restrict computation to when the value's dependents have changed.

It's possible for a single React component to have many properties that contribute to its state. Why should we recompute it if it hasn't changed if a part of the state that has nothing to do with our pricey value changes?

See the example below

import React, { useMemo } from "react";

const factorial = (n) => {
  if (n == 0) {
    return 1;
  } else {
    return n * factorial(n - 1);
  }
};

const useMemoExample = () => {
  const memoizedFactorial = useMemo(() => factorial(5), []);
  return (
    <div>
      The factorial of 5 is: {memoizedFactorial}
    </div>
  );
};

export default useMemoExample;

Enter fullscreen mode Exit fullscreen mode

The factorial function is originally defined in this code line. Then, the useMemo hook memorizes the factorial function result. UseMemo takes a function that computes the memoized value and an array of dependencies. The factorial function is memoized, and the dependents array is empty. The useMemo hook will only memoize the factorial function result if the array of dependencies does not change.

The useMemo hook is used to improve the performance of React applications by avoiding unnecessary re-renders. In this case, the factorial function is an expensive function, so it would be inefficient to calculate it on every render. By using the useMemo hook, we can memoize the result of the factorial function and only re-calculate it if the array of dependencies changes.

Caching in React with the useCallback Hook

useCallback helps you give a function as a prop to a child component without changing the function reference. If the function's dependencies don't change, useCallback can be used to memoize it.

Let's examine how JavaScript function references affect React app rendering without going into detail. Even if the function logic hasn't changed, child components that receive a function reference as a prop will re-render.

A new function reference is always regarded as a different value than the previous one because, as we've already mentioned, React only performs a shallow comparison of prop values to determine whether a component should re-render.

If a function is redeclared (even if it's the same function), the reference is updated, and the child component that uses the function as a prop must re-render.

Check the example below

import React, { useCallback } from "react";

const increment = () => {
  // Do something expensive here...
};

const useCallbackExample = () => {
  const memoizedIncrement = useCallback(increment, []);
  return (
    <button onClick={memoizedIncrement}>
      Increment
    </button>
  );
};

export default useCallbackExample;

Enter fullscreen mode Exit fullscreen mode

This code snippet first defines a function called increment that does something expensive. Then, it uses the useCallback hook to memoize the increment function. The useCallback hook takes two arguments: a function that is to be memoized, and an array of dependencies. In this case, the function to be memoized is the increment function, and the array of dependencies is empty. This means that the useCallback hook will only memoize the increment function if the array of dependencies does not change.

The useCallback hook is used to improve the performance of React applications by avoiding unnecessary re-renders. In this case, the increment function is an expensive function, so it would be inefficient to call it on every render. By using the useCallback hook, we can memoize the increment function and only call it if the array of dependencies changes.

Conculation

Caching is a key optimization strategy for React apps. Caching can help your program run faster and more efficiently by reducing the number of times it has to re-render previously rendered content.

By default, React caches data by comparing state and prop changes using a virtual DOM and only updating components after a shallow comparison. This optimization method works well and is appropriate in many situations, but there are also times when finer control is preferred.

To enable such granular management, we developed the useMemo and useCallback hooks.

When a function's result does not change frequently but is computationally expensive, useMemo can be employed to save time by storing it in memory.

To prevent unnecessary re-renders when passing functions as props to child components, useCallback can be employed to memorize the reference to the function rather than the value it returns.

Top comments (1)

Collapse
 
amirvalipouri profile image
amir valipouri

Helpful article