Module: Advanced Hooks

useMemo

useMemo is a React hook that lets you memoize the result of a calculation. React will only re-compute the memoized value when one of the dependencies changes. This is particularly useful for expensive calculations.

What problem does useMemo solve?

Without useMemo, complex calculations are re-executed on every render, even if the inputs haven’t changed. This can hurt performance in frequently re-rendered components. useMemo caches the result and avoids unnecessary re-calculations.

How does useMemo work?

useMemo takes two arguments:

  1. A calculation function: Returns the value to memoize.
  2. An array of dependencies: The memoized value is recalculated only if any dependency changes.

Syntax:

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

Example: Calculating a Fibonacci Number

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

function FibonacciComponent({ n }) {
  const [count, setCount] = useState(0);

  const fibonacci = useMemo(() => {
    console.log('Calculating Fibonacci...');
    function calculateFibonacci(num) {
      if (num <= 1) return num;
      return calculateFibonacci(num - 1) + calculateFibonacci(num - 2);
    }
    return calculateFibonacci(n);
  }, [n]);

  return (
    
		

Fibonacci of {n} is: {fibonacci}

Count: {count}

); } export default FibonacciComponent;

Explanation:

  • The fibonacci variable is memoized with useMemo.
  • The expensive calculation runs only when the n prop changes.
  • Re-rendering caused by count does not trigger recalculation of fibonacci.

When to use useMemo

  • Expensive calculations: Avoid recalculating heavy computations unnecessarily.
  • Referential equality: Maintain stable references for objects or functions passed to child components (important for React.memo).
  • Prevent unnecessary re-renders: When components re-render often but values don’t change.

useMemo vs useCallback

  • useMemo: Memoizes a value.
  • useCallback: Memoizes a function. Essentially: useCallback(fn, deps) = useMemo(() => fn, deps).

Important Considerations

  • Dependencies Array: Ensure all relevant dependencies are included to avoid stale values.
  • Overuse: Memoization has overhead; only use for actual performance bottlenecks.
  • Shallow Comparison: Objects are compared by reference. Use primitives or immutable structures for predictable behavior.
  • Garbage Collection: React may discard memoized values under memory pressure. Don’t rely on useMemo for persistent caching.

In summary, useMemo helps optimize performance by memoizing expensive calculations and maintaining referential equality. Use it judiciously for efficient, maintainable React applications.