DEV Community

Cover image for Mastering React Performance: In-Depth Guide to useCallback and useMemo. 🚀
Maitrish Mukherjee
Maitrish Mukherjee

Posted on

Mastering React Performance: In-Depth Guide to useCallback and useMemo. 🚀

Hey fellow devs, I wrote this guide hoping you won't need either another article or YouTube video on useCallback and useMemo after reading this, and you'll always have the high ground ( much like our Obi Wan above lol)

Today, let's dive deep into React performance optimization with a focus on two crucial hooks: useCallback and useMemo.

Understanding useCallback:

The Problem:
Consider a scenario where a Parent component renders a Child component, passing down a function as a prop. Without optimization, every render of the Parent component creates a new function, triggering unnecessary re-renders in the Child component.

// Parent Component
const Parent = () => {
  const handleClick = () => {
    // Some important logic
  };

  return <Child onClick={handleClick} />;
};

// Child Component
const Child = ({ onClick }) => {
  return <button onClick={onClick}>Click me</button>;
};
Enter fullscreen mode Exit fullscreen mode

The Solution:
Enter useCallback. We memoize the handleClick function to ensure that it's only recreated if the specified dependencies change. This optimization prevents unnecessary re-renders in the Child component, enhancing performance.

import { useCallback } from 'react';

// Parent Component
const Parent = () => {
  const handleClick = useCallback(() => {
    // Some important logic
  }, []); // No dependencies, because handleClick doesn't depend on anything

  return <Child onClick={handleClick} />;
};
Enter fullscreen mode Exit fullscreen mode

By understanding the intricacies of useCallback, you empower yourself to manage functions efficiently, avoiding unnecessary recalculations.

Decoding useMemo:

The Challenge:
Let's consider a component responsible for calculating a Fibonacci sequence. Without optimization, the component recalculates the Fibonacci sequence on every render, leading to redundant computations.

// Fibonacci Component
const Fibonacci = ({ n }) => {
  const calculateFibonacci = () => {
    // Expensive Fibonacci calculation
    return result;
  };

  const result = calculateFibonacci();

  return <div>{result}</div>;
};
Enter fullscreen mode Exit fullscreen mode

The Solution:
Introducing useMemo. We memoize the result of the expensive Fibonacci calculation, ensuring it only recalculates when the specified dependencies change. This optimization prevents unnecessary computations, especially when n remains constant.

import { useMemo } from 'react';

// Fibonacci Component
const Fibonacci = ({ n }) => {
  const result = useMemo(() => {
    // Expensive Fibonacci calculation
    return calculateFibonacci(n);
  }, [n]);

  return <div>{result}</div>;
};
Enter fullscreen mode Exit fullscreen mode

By incorporating useMemo, you gain control over costly computations, making your components more efficient and performant.

When to Use Them Together:

Practical Scenario:
Imagine a list of items with a button to perform an action on each item. We want to optimize the performance of each item, avoiding unnecessary re-renders and computations.

// List Component
const List = ({ items }) => {
  const handleClick = useCallback((item) => {
    // Do something with the item
  }, []);

  return (
    <ul>
      {items.map((item) => (
        <ListItem key={item.id} item={item} onClick={handleClick} />
      ))}
    </ul>
  );
};

// ListItem Component
const ListItem = ({ item, onClick }) => {
  const result = useMemo(() => {
    // Expensive computation based on item
    return calculateResult(item);
  }, [item]);

  return (
    <li>
      {result}
      <button onClick={() => onClick(item)}>Perform Action</button>
    </li>
  );
};
Enter fullscreen mode Exit fullscreen mode

In this scenario, the combination of useCallback for the click handler and useMemo for the computation result ensures optimal performance for each item in the list.

In Conclusion:

As React professionals, understanding the depth of useCallback and useMemo empowers us to craft high-performance applications. These optimizations, when applied judiciously, elevate your React code to new levels of efficiency. Embrace these tools, and may your React applications run smoother than ever before!

Please comment down below if this helped you!

Top comments (0)