DA

dev Await

February 2025

Understanding useCallback and useMemo

Introduction

useCallback and useMemo are React hooks used for performance optimization. They help prevent unnecessary re-renders of components by memoizing values and functions.

useCallback 🔄

What is useCallback?

useCallback is a hook that returns a memoized version of a callback function that only changes if one of its dependencies changes.

When to Use?

  • When passing callbacks to optimized child components that rely on reference equality

  • To prevent unnecessary re-renders in child components

  • When working with complex event handlers

Basic Example:

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

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

  // Without useCallback - function recreated on every render
  const handleClick = () => {
    setCount(count + 1);
  };

  // With useCallback - function memoized
  const handleClickMemoized = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, []); // Empty dependency array as it uses functional update

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

const ChildComponent = React.memo(({ onPress }) => {
  console.log("Child rendered");
  return <button onClick={onPress}>Add</button>;
});

useMemo 📝

What is useMemo?

useMemo is a hook that returns a memoized value. It only recomputes the value when one of the dependencies changes.

When to Use?

  • For expensive calculations

  • When dealing with complex data transformations

  • To prevent unnecessary re-computations

Basic Example:

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

const ExpensiveComponent = () => {
  const [numbers] = useState([1, 2, 3, 4, 5]);
  const [count, setCount] = useState(0);

  // Without useMemo - calculated on every render
  const sum = numbers.reduce((acc, num) => acc + num, 0);

  // With useMemo - only calculated when numbers change
  const memoizedSum = useMemo(() => {
    return numbers.reduce((acc, num) => acc + num, 0);
  }, [numbers]);

  return (
    <div>
      <p>Sum: {memoizedSum}</p>
      <button onClick={() => setCount(count + 1)}>
        Click count: {count}
      </button>
    </div>
  );
};

Key Differences 🔍

  1. Purpose

    • useCallback: Memoizes functions

    • useMemo: Memoizes values

  2. Usage

    // useCallback
    const memoizedFn = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
    
    // useMemo
    const memoizedValue = useMemo(() => {
      return computeExpensiveValue(a, b);
    }, [a, b]);

Best Practices 💡

  1. Don't Overuse

    • Only use when there's a clear performance benefit

    • Profile your app to identify actual performance issues

  1. Proper Dependencies

    // Good
    const memoizedValue = useMemo(() => {
      return expensiveOperation(prop);
    }, [prop]);
    
    // Bad - missing dependency
    const memoizedValue = useMemo(() => {
      return expensiveOperation(prop);
    }, []); // ESLint will warn about this
  2. Use with React.memo

    const ChildComponent = React.memo(({ callback }) => {
      return <button onClick={callback}>Click me</button>;
    });
    
    const ParentComponent = () => {
      const callback = useCallback(() => {
        // handle click
      }, []);
    
      return <ChildComponent callback={callback} />;
    };

When Not to Use 🚫

  1. Simple calculations

  2. Components that always need to re-render

  3. When there's no clear performance benefit

That's the essential guide to useCallback and useMemo! Remember to use them only when necessary for performance optimization. Happy coding! 🚀

devawait.png

Copyright © 2025 DevAwait. All rights reserved.