React JS: useMemo vs memo - A Comprehensive Guide

As a React developer, optimizing performance is crucial. Two tools that help with this are useMemo and memo. Let’s break them down with easy examples.

What is useMemo?

useMemo is a React Hook that remembers (or “memoizes”) the result of a calculation. This means it stores the result and only recalculates it when certain values (dependencies) change. This is great for expensive calculations that don’t need to be repeated every time a component re-renders.

Simple Example:

import React, { useMemo } from 'react';

function ExpensiveCalculation({ a, b }) {
  // Only recalculate when 'a' or 'b' changes
  const result = useMemo(() => {
    console.log('Calculating...');
    return a * b; // Expensive calculation
  }, [a, b]);

  return <div>Result: {result}</div>;
}

function App() {
  const [count, setCount] = React.useState(0);
  
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Re-render ({count})</button>
      <ExpensiveCalculation a={5} b={10} />
    </div>
  );
}

What happens here?

  • ExpensiveCalculation calculates a * b (5 * 10 = 50).
  • Even when the parent (App) re-renders (e.g., when you click the button), ExpensiveCalculation won’t recalculate unless a or b changes.
  • You’ll only see “Calculating…” once, not on every click.

What is memo?

memo is a higher-order component that prevents a component from re-rendering if its props haven’t changed. It’s like a “smart” component that only updates when necessary.

Simple Example:

import React, { memo } from 'react';

const Greeting = memo(({ name }) => {
  console.log('Greeting rendered!');
  return <div>Hello, {name}!</div>;
});

function App() {
  const [count, setCount] = React.useState(0);
  
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Re-render ({count})</button>
      <Greeting name="Alice" />
    </div>
  );
}

What happens here?

  • Greeting only re-renders if its name prop changes.
  • Even when count changes (and App re-renders), Greeting doesn’t re-render because name (“Alice”) stays the same.
  • You’ll only see “Greeting rendered!” once, not on every click.

useMemo vs memo: Key Differences

FeatureuseMemomemo
What it doesMemoizes values (e.g., calculations)Memoizes components (prevents re-renders)
How it worksUses a dependency array ([a, b])Uses prop comparison
Best forExpensive calculationsComponents with stable props

When to Use useMemo

  1. Slow calculations: If a computation takes time (e.g., filtering a big list), use useMemo to avoid repeating it.
  2. Derived data: If you compute something from props/state (e.g., totalPrice = items.reduce(...)), useMemo can help.

Example:

const total = useMemo(() => {
  return items.reduce((sum, item) => sum + item.price, 0);
}, [items]); // Only recalculate if 'items' changes

When to Use memo

  1. Stable props: If a child component receives the same props repeatedly, memo can skip re-rendering.
  2. Performance issues: If a component is slow to render, memo might help.

Example:

const UserCard = memo(({ user }) => {
  return <div>{user.name}</div>;
});

// Only re-renders if 'user' changes
<UserCard user={{ id: 1, name: "Bob" }} />

Common Mistakes & Tips

1. Don’t overuse them!

  • Only use useMemo/memo when you see a real performance issue.
  • Premature optimization can make code harder to read.

2. memo and objects/arrays

  • memo does a shallow compare of props. If you pass a new object/array every time, it may not work as expected.
  • Fix: Use useMemo for object/array props or a custom comparison function.

3. Missing dependencies in useMemo

  • Always include all variables used in the calculation in the dependency array.
  • Example:
    const result = useMemo(() => a * b, [a, b]); // ✅ Correct

Combining useMemo and memo

You can use both together for maximum optimization!

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

const Calculator = memo(({ a, b }) => {
  const result = useMemo(() => {
    console.log('Calculating...');
    return a + b;
  }, [a, b]);

  return <div>Result: {result}</div>;
});

function App() {
  const [count, setCount] = React.useState(0);
  
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Re-render ({count})</button>
      <Calculator a={3} b={7} />
    </div>
  );
}

What happens here?

  • Calculator won’t re-render unless a or b changes (thanks to memo).
  • Even if it does re-render, the calculation is memoized (thanks to useMemo).

FAQs

Q1: What’s the difference between useMemo and useCallback?

  • useMemo memoizes values (e.g., const x = 1 + 2).
  • useCallback memoizes functions (e.g., const fn = () => {...}).

Q2: Can I use memo with class components?

  • No, memo is for functional components. Use PureComponent for classes.

Q3: Does useMemo prevent re-renders?

  • No, it only memoizes values. To prevent re-renders, use memo.

Q4: When should I avoid useMemo?

  • Avoid it for simple calculations (e.g., a + b). The overhead might outweigh the benefit.

Conclusion

  • useMemo: For optimizing calculations (values).
  • memo: For optimizing components (re-renders).
  • Use them wisely—only when needed!

Reading Further


Happy coding! 🚀


React js useMemo memo React performance optimization React hooks React memoization