Craig Jones

Hi there đź‘‹

My name is Craig. I am a Software Engineer based in the NW of England. This blog will be a dump of my learnings. Expect it to be littered with Tech articles, DIY and trying to learn more about my Ford Focus ST.

tech

Understanding useMemo and useCallback in React

useMemo + useCallback
Understanding useMemo and useCallback in React

Understanding useMemo and useCallback in React

React, the popular JavaScript library for building user interfaces, provides several hooks to optimize performance and manage state in functional components. Two commonly used hooks for optimization are useMemo and useCallback. While both serve similar purposes, they have distinct use cases and can significantly enhance the efficiency of your React applications.

useMemo: Memoizing Values for Performance

The useMemo hook is used to memoize the result of a computation. It memoizes a value so that it is only recomputed when the dependencies provided in the dependency array change. This can be particularly useful when dealing with expensive calculations or operations that don’t need to be recalculated on every render.

import React, { useMemo, useState } from 'react';

const SquareCalculator = ({ number }) => {
  const squaredValue = useMemo(() => {
    return number * number;
  }, [number]);

  return (
    <div>
      <p>Original Number: {number}</p>
      <p>Squared Value: {squaredValue}</p>
    </div>
  );
};

// Usage
const MyApp = () => {
  const [value, setValue] = useState(5);

  return (
    <div>
      <SquareCalculator number={value} />
      <button onClick={() => setValue(value + 1)}>Increment</button>
    </div>
  );
};

In this example, the squaredValue is memoized using useMemo. The calculation is only performed when the number prop changes.

useCallback: Memoizing Functions for Performance

The useCallback hook, on the other hand, is specifically designed for memoizing functions. It is useful when passing functions as props to child components, preventing unnecessary re-renders of those components.

import React, { useCallback, useState } from 'react';

const ChildComponent = ({ onClick }) => {
  // Some child component logic

  return <button onClick={onClick}>Click me</button>;
};

const ParentComponent = () => {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <ChildComponent onClick={handleClick} />
    </div>
  );
};

In this example, the handleClick function is memoized using useCallback. This ensures that the function reference remains the same unless the count dependency changes, preventing unnecessary re-renders of the ChildComponent.

When to Use useMemo and useCallback

Use useMemo when:

  • You need to memoize the result of a computation.
  • You have a complex calculation that doesn’t need to be recalculated on every render.
  • You want to optimize the performance of components that rely on expensive computations.

Use useCallback when:

  • You need to memoize a function to prevent unnecessary re-renders of components that receive that function as a prop.
  • You want to optimize the performance of components that rely on callback functions.

When Not to Use useMemo and useCallback

Avoid using useMemo when:

  • The calculation is simple and doesn’t add significant overhead.
  • The calculated value is needed on every render.

Avoid using useCallback when:

  • The function doesn’t cause unnecessary re-renders, and its reference changing is acceptable.
  • The function doesn’t have dependencies, and its reference changing won’t impact performance.

By understanding the differences between useMemo and useCallback and their appropriate use cases, you can optimize the performance of your React applications effectively. These hooks are powerful tools in your optimization toolbox, and using them judiciously can lead to smoother and more efficient user interfaces.

Kent Dodds writes a great article on this subject. I would definitely give that a read - https://kentcdodds.com/blog/usememo-and-usecallback

Also attached are some really useful benchmarking images to show how useMemo affects render times. These are found in this Medium article.