Popular Searches
Popular Course Categories
Popular Courses

useMemo Hook

useMemo Hook

Advanced React Hooks

useMemo Hook in React JS

The useMemo Hook is a built-in React Hook that helps improve performance by caching the result of a calculation between component re-renders. React can reuse the previously calculated value when its dependencies have not changed, instead of performing the calculation again. It is particularly useful when working with expensive calculations, large lists, filtering, sorting, and optimized child components.

Course: JustAcademy React JS Training Course

Course Demo: Register for React JS Course Demo


1. What Is the useMemo Hook?

useMemo is used to cache the result of a calculation so React can reuse it during later renders when the dependencies remain unchanged. This technique is called memoization.

By default, React executes the component function again when the component re-renders. Calculations inside the component body are normally performed again. If a calculation is expensive, useMemo can help avoid unnecessary recalculations.

Syntax

const cachedValue = useMemo(() => {
  return calculateValue();
}, [dependency1, dependency2]);

Explanation:

  • useMemo is the React Hook used for memoization.
  • () => calculateValue() is the calculation function.
  • [dependency1, dependency2] is the dependency array.
  • cachedValue stores the calculated result returned by the Hook.

2. Why Do We Use useMemo?

  • Improve performance: Avoid repeating expensive calculations when the relevant inputs have not changed.
  • Optimize list operations: Cache the results of filtering, sorting, or transforming large arrays.
  • Preserve value references: Reuse the same object or array reference while dependencies remain unchanged.
  • Support memoized child components: Help prevent unnecessary child re-renders when the child uses memo and its props remain unchanged.
  • Stabilize dependencies: Sometimes prevent an object dependency from changing on every render.

Important: useMemo is a performance optimization, not a requirement for every calculation. Most simple calculations do not need it.


3. How Does useMemo Work?

  1. React renders the component for the first time.
  2. The calculation function passed to useMemo runs.
  3. React returns the calculated value and caches it.
  4. When the component renders again, React compares the current dependencies with the previous ones.
  5. If the dependencies have not changed, React can reuse the cached value.
  6. If one or more dependencies have changed, React recalculates the value.

Flow Diagram

Component Renders
       |
       v
useMemo Checks Dependencies
       |
       v
Have Dependencies Changed?
       |
   +---+---+
   |       |
  No      Yes
   |       |
   v       v
Reuse    Recalculate
Cached   the Value
Value       |
   |       |
   +---+---+
       |
       v
Return the Value

React compares dependency values using Object.is. The dependency array must contain the reactive values used by the calculation.


4. First Example: useMemo with a Simple Calculation

This example calculates the square of a number using useMemo.

import { useMemo, useState } from "react";
function SquareCalculator() {
  const [number, setNumber] = useState(2);
  const [theme, setTheme] = useState(false);
  const square = useMemo(() => {
    console.log("Calculating square...");
    return number * number;
  }, [number]);
  return (
    <div style={{
      background: theme ? "#222" : "#fff",
      color: theme ? "#fff" : "#222",
      padding: "20px"
    }}>
      <h2>Square: {square}</h2>
      <button onClick={() => setNumber(number + 1)}>
        Increase Number
      </button>
      <button onClick={() => setTheme(!theme)}>
        Toggle Theme
      </button>
    </div>
  );
}
export default SquareCalculator;

Explanation:

  • number stores the number entered into the calculation.
  • square stores the result of number * number.
  • The dependency array contains [number].
  • When the number changes, React recalculates the square.
  • When only the theme changes, React can reuse the cached square.

This calculation is simple, so memoization is not necessary in a real application. It is used here to demonstrate how the Hook works.


5. useMemo with Expensive Calculations

An expensive calculation takes a noticeable amount of time or processing power. Examples include processing large datasets, filtering thousands of records, or performing complex mathematical operations.

Example

import { useMemo, useState } from "react";
function ExpensiveCalculation() {
  const [number, setNumber] = useState(100);
  const [theme, setTheme] = useState(false);
  const result = useMemo(() => {
    let total = 0;
    for (let i = 0; i < number * 1000; i++) {
      total += i;
    }
    return total;
  }, [number]);
  return (
    <div style={{ color: theme ? "blue" : "black" }}>
      <h2>Result: {result}</h2>
      <button onClick={() => setNumber(number + 10)}>
        Change Number
      </button>
      <button onClick={() => setTheme(!theme)}>
        Change Theme
      </button>
    </div>
  );
}
export default ExpensiveCalculation;

Explanation: The calculation runs when the component initially renders and when number changes. If only theme changes, React can reuse the cached result.

Note: This is a demonstration, not a benchmark. Use profiling to determine whether a calculation is expensive enough to benefit from memoization.


6. Understanding the Dependency Array

The dependency array tells React which reactive values affect the calculation. When any dependency changes, React recalculates the value.

Example with One Dependency

const doubled = useMemo(() => {
  return count * 2;
}, [count]);

The calculation is repeated when count changes.

Example with Multiple Dependencies

const total = useMemo(() => {
  return price * quantity;
}, [price, quantity]);

The calculation is repeated when either price or quantity changes.

Example with an Empty Dependency Array

const initialMessage = useMemo(() => {
  return "Welcome to React";
}, []);

The calculation normally runs during the initial render and its result is reused on subsequent renders. React may discard the cached value for specific reasons, so useMemo should not be used as a guarantee that a value will exist permanently.

Important Dependency Rules

  • Include all reactive values used inside the calculation.
  • Do not leave out dependencies simply to prevent recalculation.
  • Keep the dependency array inline and maintain a constant number of dependencies.
  • React compares dependency values using Object.is.

7. useMemo with Arrays and Filtering

useMemo is often useful when filtering or transforming large arrays. It can reuse the filtered result when the source array and filter value remain unchanged.

Example: Product Search

import { useMemo, useState } from "react";
const products = [
  { id: 1, name: "Laptop", price: 50000 },
  { id: 2, name: "Mobile", price: 20000 },
  { id: 3, name: "Headphones", price: 2000 },
  { id: 4, name: "Keyboard", price: 1500 }
];
function ProductSearch() {
  const [search, setSearch] = useState("");
  const [showAffordable, setShowAffordable] = useState(false);
  const filteredProducts = useMemo(() => {
    return products.filter(product => {
      const matchesSearch = product.name
        .toLowerCase()
        .includes(search.toLowerCase());
      const matchesPrice = !showAffordable || product.price <= 20000;
      return matchesSearch && matchesPrice;
    });
  }, [search, showAffordable]);
  return (
    <div>
      <h2>Product Search</h2>
      <input
        type="text"
        value={search}
        onChange={event => setSearch(event.target.value)}
        placeholder="Search products"
      />
      <label>
        <input
          type="checkbox"
          checked={showAffordable}
          onChange={event => setShowAffordable(event.target.checked)}
        />
        Show products up to ₹20,000
      </label>
      <ul>
        {filteredProducts.map(product => (
          <li key={product.id}>
            {product.name} - ₹{product.price}
          </li>
        ))}
      </ul>
    </div>
  );
}
export default ProductSearch;

Explanation:

  • products contains the product data.
  • search stores the search text.
  • showAffordable controls the price filter.
  • filteredProducts stores the memoized filtered array.
  • The filtering calculation runs again when either dependency changes.

For a small array, filtering directly may be perfectly adequate. Memoization is most useful when the calculation is costly or when preserving the array reference helps an optimized child component.


8. useMemo with Object Values

JavaScript creates a new object when an object literal is evaluated. Even if two objects contain identical properties, they are different references.

Example

const user = useMemo(() => {
  return {
    name: "Amit",
    role: "Developer"
  };
}, []);

React can reuse this object reference between renders while the cached value is retained.

When Is This Useful?

  • When an object is passed as a prop to a child wrapped with memo.
  • When a memoized object is used as a dependency of another Hook.
  • When creating the object is part of an expensive calculation.

Do not use useMemo for every object. Often, restructuring the code is simpler and more reliable than memoizing an object solely to preserve its reference.


9. useMemo with Child Components and memo

The memo function can help a child component skip re-rendering when its props remain unchanged. However, if the parent creates a new array or object on every render, the child may receive a different prop reference each time.

Example

import { memo, useMemo, useState } from "react";
const ProductList = memo(function ProductList({ products }) {
  console.log("ProductList rendered");
  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  );
});
function ProductPage() {
  const [theme, setTheme] = useState(false);
  const [count, setCount] = useState(0);
  const products = useMemo(() => [
    { id: 1, name: "Laptop" },
    { id: 2, name: "Mobile" }
  ], []);
  return (
    <div style={{ background: theme ? "#ddd" : "#fff" }}>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>
        Increase Count
      </button>
      <button onClick={() => setTheme(!theme)}>
        Change Theme
      </button>
      <ProductList products={products} />
    </div>
  );
}
export default ProductPage;

Explanation: The products array keeps the same reference between renders while the memoized value is retained. Because ProductList is wrapped in memo, it can skip re-rendering when its props have not changed.

Important: memo and useMemo are performance optimizations, not guarantees. A child may still render when its own state or context changes, and React may discard a memoized value in certain circumstances.


10. Difference Between useMemo and useCallback

Both Hooks use dependency arrays, but they cache different things.

Feature useMemo useCallback
Purpose Caches the result of a calculation. Caches a function definition.
Returns The calculated value. The function itself.
Typical use Filtering, sorting, or expensive calculations. Passing a stable callback to an optimized child.
Syntax useMemo(() => calculate(), [value]) useCallback(() => handleClick(), [value])

useMemo Example

const total = useMemo(() => {
  return price * quantity;
}, [price, quantity]);

useCallback Example

const handleClick = useCallback(() => {
  console.log("Current count:", count);
}, [count]);

Remember: Use useMemo for a cached value and useCallback for a cached function definition.


11. useMemo vs. Calculating Directly

Not every calculation requires memoization. For simple operations, calculating the value directly is usually easier to read.

Without useMemo

function Price({ price, quantity }) {
  const total = price * quantity;
  return <p>Total: ₹{total}</p>;
}

With useMemo

function Price({ price, quantity }) {
  const total = useMemo(() => {
    return price * quantity;
  }, [price, quantity]);
  return <p>Total: ₹{total}</p>;
}

Both examples calculate the same total. For a simple multiplication, useMemo usually provides no meaningful benefit. It is better suited to expensive calculations or situations where a stable reference is useful.


12. Common useMemo Mistakes

Mistake Problem Correct Approach
Using useMemo for every calculation Adds unnecessary complexity. Memoize when there is a measurable or practical benefit.
Missing dependencies The calculation may use outdated values. Include all reactive values used by the calculation.
Forgetting the dependency array The calculation runs on every render. Provide the dependency array when caching is needed.
Performing side effects inside useMemo The calculation is not pure and may run more than expected. Use event handlers or an appropriate effect for side effects.
Calling useMemo conditionally Breaks the Rules of Hooks. Call it at the top level of the component or custom Hook.
Forgetting to return a value The memoized result may be undefined. Return the calculated value.
Expecting useMemo to stop all renders It caches a calculation, not the entire component. Understand how state, props, context, and memoization interact.
Using it as permanent storage React may discard the cache in specific situations. Use state or a ref when persistent storage is required.

13. Rules of the useMemo Hook

  • Call useMemo at the top level of a React function component or custom Hook.
  • Do not call it inside loops, conditions, or nested functions.
  • Pass a calculation function that returns the desired value.
  • Include all reactive values used by the calculation in the dependency array.
  • Keep the calculation pure and free of side effects.
  • Use the cached result only as a performance optimization.
  • Do not modify arrays or objects received from props or state while calculating a memoized value.
  • Use React Developer Tools Profiler to investigate actual performance problems.

14. Understanding Strict Mode with useMemo

When React Strict Mode is enabled, React may call the calculation function twice during development to help identify impure calculations. One result is ignored. This extra check does not occur in the same way in production.

Example

const result = useMemo(() => {
  console.log("Calculating result");
  return numbers.reduce((sum, number) => sum + number, 0);
}, [numbers]);

The console message may appear twice during development when Strict Mode performs its checks. This does not necessarily mean that the dependency array is incorrect.

Best practice: Keep memoized calculations pure. Do not send API requests, update state, modify the DOM, or change external data inside a useMemo calculation.


15. Practical Project: Student Marks Calculator

Create a student marks application that calculates the average score and determines whether a student has passed. This example demonstrates memoizing a calculation based on an array of marks.

Complete Code

import { useMemo, useState } from "react";
function StudentMarks() {
  const [marks, setMarks] = useState([80, 75, 90]);
  const [studentName, setStudentName] = useState("Amit");
  const average = useMemo(() => {
    if (marks.length === 0) {
      return 0;
    }
    const total = marks.reduce((sum, mark) => sum + mark, 0);
    return total / marks.length;
  }, [marks]);
  const status = average >= 40 ? "Pass" : "Fail";
  function addMarks() {
    setMarks(currentMarks => [...currentMarks, 85]);
  }
  return (
    <div>
      <h2>Student Marks Calculator</h2>
      <label>
        Student Name:
        <input
          value={studentName}
          onChange={event => setStudentName(event.target.value)}
        />
      </label>
      <p>Student: {studentName}</p>
      <p>Marks: {marks.join(", ")}</p>
      <p>Average: {average.toFixed(2)}</p>
      <p>Result: {status}</p>
      <button onClick={addMarks}>Add Marks</button>
    </div>
  );
}
export default StudentMarks;

Project Explanation

  • marks stores the student's scores.
  • studentName stores the student's name.
  • useMemo calculates the average using the marks array.
  • The average is recalculated when the marks dependency changes.
  • Changing only the student's name does not require recalculating the average.
  • The pass/fail status is a simple derived value, so it does not need its own state or an effect.

16. Performance Optimization Tips

  • Start by writing simple, readable code.
  • Use useMemo for calculations that are expensive enough to affect responsiveness.
  • Memoize derived arrays or objects when stable references help optimized child components.
  • Avoid creating unnecessary effects that update state and cause chains of re-renders.
  • Do not expect useMemo to make the initial render faster; its main purpose is to skip repeated work on later renders.
  • Measure performance in realistic conditions instead of assuming memoization is needed.
  • Consider React Compiler, when enabled in your project, because it can automatically memoize values and functions and reduce the need for manual memoization.

17. Interview Questions and Answers

Q1. What is useMemo in React?

useMemo is a React Hook that caches the result of a calculation between renders while its dependencies remain unchanged.

Q2. What is memoization?

Memoization is an optimization technique that stores the result of a calculation and reuses it when the relevant inputs have not changed.

Q3. What does useMemo return?

It returns the calculated value, either by running the calculation function or reusing a cached result.

Q4. What is the purpose of the dependency array?

The dependency array specifies the reactive values used by the calculation. React compares them with the previous values to determine whether recalculation is necessary.

Q5. What happens when a dependency changes?

React reruns the calculation and returns the updated value.

Q6. What happens when the dependency array is empty?

The calculation normally runs during the initial render, and React can reuse the cached result during later renders while the cache is retained.

Q7. What is the difference between useMemo and useCallback?

useMemo caches a calculated value, whereas useCallback caches a function definition.

Q8. Does useMemo prevent a component from re-rendering?

No. It caches a calculation result. It can indirectly help an optimized child component skip re-rendering when a memoized prop remains unchanged.

Q9. Can useMemo be used for API calls?

No. useMemo is for pure calculations, not side effects such as API requests. API synchronization generally belongs in an appropriate effect or data-fetching solution.

Q10. Can useMemo be called inside a loop?

No. It must be called at the top level of a React function component or custom Hook.

Q11. Is useMemo always necessary?

No. Use it when it provides a practical performance benefit or a useful stable reference. Simple calculations can usually be performed directly.

Q12. What is the difference between useMemo and useState?

useMemo caches the result of a calculation, while useState stores state that can be updated to trigger a re-render.


18. Practice Exercises

  1. Create a component that calculates the square of a number using useMemo.
  2. Build a product filter that filters items by name and price.
  3. Calculate a shopping cart total from an array of products.
  4. Create a student marks calculator that displays an average score.
  5. Use useMemo to preserve an array reference passed to a child wrapped with memo.
  6. Find and correct a missing dependency in a memoized calculation.
  7. Identify a calculation that does not need useMemo and simplify the code.
  8. Use React Developer Tools Profiler to investigate a slow calculation.

19. Quick Revision Checklist

  • Understand the meaning of memoization.
  • Know the syntax of useMemo.
  • Understand how dependency arrays control recalculation.
  • Know how to optimize expensive calculations.
  • Understand the difference between useMemo and useCallback.
  • Know how stable references can help memoized child components.
  • Avoid unnecessary memoization.
  • Keep calculation functions pure.
  • Follow the Rules of Hooks.
  • Measure performance before applying optimizations.

20. Conclusion

The useMemo Hook helps React applications avoid unnecessary repeated calculations by caching values between renders. It is useful for expensive computations, large-list filtering, and preserving references when working with optimized child components. For best results, include the correct dependencies, keep calculations pure, and use memoization only when it provides a real benefit.

Official React Documentation: React useMemo Hook | React memo | React useCallback Hook

Explore the Course: JustAcademy React JS Training Course | Register for React JS Course Demo

whatsapp