Lesson 34 of 60 – useMemo Hook
57%

useMemo Hook

The useMemo Hook is used to memorize the result of a calculation so that React can reuse the previously calculated value when the dependencies have not changed.

Note: useMemo can help avoid unnecessary expensive calculations. It should be used when memoization provides a real benefit, not for every calculation.

1. What is useMemo?

useMemo is a React Hook that memoizes a calculated value.

const result = useMemo(
    () => calculateValue(),
    [dependency]
);

React can reuse the memoized result when the dependencies remain unchanged.

2. Why use useMemo?

Normally, JavaScript calculations inside a component run whenever the component renders.

If a calculation is expensive, repeatedly performing it may be unnecessary when its input values have not changed.

const result = expensiveCalculation(data);

useMemo can cache the result based on dependencies.

3. Importing useMemo

Import useMemo from React before using it.

import { useMemo } from "react";

You can also import it along with other React Hooks.

import {
    useMemo,
    useState
} from "react";

4. Basic useMemo Syntax

const value = useMemo(
    () => {
        return calculation;
    },
    [dependencies]
);

The first argument is a function that calculates the value. The second argument is the dependency array.

5. Memoized Value

The value returned by useMemo is the result of the calculation function.

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

The calculation runs again when price or quantity changes.

6. Dependency Array

The dependency array tells React which values the calculation depends on.

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

If the dependencies do not change between renders, React can reuse the previous result.

7. Simple useMemo Example

import { useMemo } from "react";

function Product() {

    const price = 100;
    const quantity = 5;

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

    return (
        <h2>
            Total: ₹{total}
        </h2>
    );
}

export default Product;

8. useMemo with useState

useMemo is often demonstrated with state values.

const [number, setNumber] =
    useState(10);

const square = useMemo(
    () => number * number,
    [number]
);

The square is recalculated when number changes.

9. Expensive Calculation

An expensive calculation may take significant time or processing resources.

function expensiveCalculation(number) {

    console.log("Calculating...");

    let result = 0;

    for(let i = 0; i < 1000000; i++) {
        result += number * i;
    }

    return result;
}

Memoization can prevent this calculation from running unnecessarily when its inputs have not changed.

10. Memoizing an Expensive Calculation

const result = useMemo(
    () => expensiveCalculation(number),
    [number]
);

The calculation depends on number, so number is included in the dependency array.

11. useMemo and Re-rendering

A component can re-render because its state or props change. During a render, normal calculations in the component body can run again.

With useMemo, a memoized calculation can reuse its previous result when its dependencies have not changed.

12. useMemo with a Counter

function App() {

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

    const [number, setNumber] =
        useState(5);

    const square = useMemo(
        () => number * number,
        [number]
    );

    return (
        <div>

            <h2>
                Count: {count}
            </h2>

            <h2>
                Square: {square}
            </h2>

            <button
                onClick={() =>
                    setCount(count + 1)
                }
            >
                Increase Count
            </button>

            <button
                onClick={() =>
                    setNumber(number + 1)
                }
            >
                Increase Number
            </button>

        </div>
    );
}

13. Only Dependencies Trigger Recalculation

Suppose a memoized calculation depends only on number.

const square = useMemo(
    () => number * number,
    [number]
);

Changing an unrelated state value does not change the dependency number, so the previous memoized result can be reused.

14. useMemo with Arrays

useMemo can be useful when filtering or transforming an array is expensive.

const filteredStudents = useMemo(
    () => students.filter(
        student => student.active
    ),
    [students]
);

15. Filtering a List with useMemo

const activeStudents = useMemo(
    () => {

        return students.filter(
            student =>
                student.status === "active"
        );

    },
    [students]
);

The filtering operation is recalculated when the students reference changes.

16. useMemo with Search

A search result can be memoized when filtering a large list.

const results = useMemo(
    () => {

        return students.filter(
            student =>
                student.name
                .toLowerCase()
                .includes(search.toLowerCase())
        );

    },
    [students, search]
);

Both students and search are dependencies.

17. useMemo with Sorting

Sorting a large array can also be a calculation that you may choose to memoize.

const sortedStudents = useMemo(
    () => {

        return [...students].sort(
            (a, b) =>
                a.name.localeCompare(b.name)
        );

    },
    [students]
);

The spread operator creates a new array instead of directly mutating the original array.

18. useMemo with Objects

useMemo can also preserve the same object reference until its dependencies change.

const userInfo = useMemo(
    () => ({
        name: name,
        role: role
    }),
    [name, role]
);

The object is recreated when name or role changes.

19. useMemo and Referential Equality

Objects and arrays are compared by reference in JavaScript. Creating a new object on every render creates a new reference.

const user = {
    name: "Rahul"
};

If the same object reference is important for optimization, a memoization technique such as useMemo may be useful.

20. useMemo vs Normal Calculation

Normal Calculation useMemo
Runs during each relevant render. Can reuse a memoized result.
No dependency array. Uses a dependency array.
Simple calculations are usually enough. Useful for selected expensive calculations.
Easy to read. Adds memoization complexity.

21. useMemo vs useCallback

useMemo useCallback
Memoizes a calculated value. Memoizes a function reference.
Returns a value. Returns a function.
Useful for expensive calculations. Useful when function reference stability matters.
const value = useMemo(
    () => calculate(),
    [data]
);

const handleClick = useCallback(
    () => doSomething(),
    [data]
);

22. useMemo Does Not Prevent Rendering

It is important to understand that useMemo does not stop the component itself from rendering.

It memoizes the result of a calculation so that React can reuse that value when appropriate.

const result = useMemo(
    () => expensiveCalculation(data),
    [data]
);

23. Avoid Unnecessary useMemo

Not every calculation needs memoization.

const total = price + tax;

For a simple and inexpensive calculation, adding useMemo may make the code more complicated without a meaningful benefit.

24. useMemo with Multiple Dependencies

const total = useMemo(
    () => {

        return price *
               quantity *
               discount;

    },
    [price, quantity, discount]
);

Every value used by the calculation that can change should be considered when defining dependencies.

25. useMemo and Derived Data

Derived data is information calculated from existing state or props.

const totalMarks = useMemo(
    () => {

        return marks.reduce(
            (total, mark) =>
                total + mark,
            0
        );

    },
    [marks]
);

The total is derived from the marks array.

26. useMemo with React Components

useMemo can be used inside a component to memoize calculated data that is passed to another component.

const filteredProducts = useMemo(
    () =>
        products.filter(
            product =>
                product.price < 1000
        ),
    [products]
);

return (
    <ProductList
        products={filteredProducts}
    />
);

27. Common useMemo Mistakes

  • Using useMemo for every calculation.
  • Forgetting required dependencies.
  • Adding incorrect dependencies.
  • Expecting useMemo to prevent component rendering.
  • Using it for very simple calculations without a reason.
  • Mutating arrays or objects inside calculations.
  • Using useMemo when the code becomes harder to understand without a real benefit.

28. Complete Search Example

import {
    useMemo,
    useState
} from "react";

function StudentSearch() {

    const [search, setSearch] =
        useState("");

    const students = [
        { id: 1, name: "Rahul" },
        { id: 2, name: "Amit" },
        { id: 3, name: "Priya" }
    ];

    const filteredStudents =
        useMemo(
            () => {

                return students.filter(
                    student =>
                        student.name
                        .toLowerCase()
                        .includes(
                            search.toLowerCase()
                        )
                );

            },
            [search]
        );

    return (
        <div>

            <input
                value={search}
                onChange={(e) =>
                    setSearch(e.target.value)
                }
                placeholder="Search student"
            />

            {filteredStudents.map(
                student => (
                    <p key={student.id}>
                        {student.name}
                    </p>
                )
            )}

        </div>
    );
}

export default StudentSearch;

29. useMemo Workflow

The basic workflow of useMemo is:

  1. Identify a calculation that may be expensive.
  2. Place the calculation inside the useMemo callback.
  3. Add the values used by the calculation to the dependency array.
  4. React calculates the value when needed.
  5. If dependencies remain unchanged, React can reuse the memoized value.
  6. If a dependency changes, the calculation runs again.
Component Render
       ↓
   useMemo()
       ↓
Check Dependencies
       ↓
 ┌─────┴─────┐
 ↓           ↓
Same       Changed
 ↓           ↓
Reuse     Calculate
Value       Again

30. useMemo Best Practices

  • Use useMemo for calculations where memoization provides a useful benefit.
  • Keep the dependency array accurate.
  • Do not use useMemo for every small calculation.
  • Keep memoized calculations easy to understand.
  • Use it for expensive filtering, sorting, or derived data when appropriate.
  • Remember that useMemo memoizes a value, not a function.
  • Use useCallback when the goal is to memoize a function reference.
  • Do not expect useMemo to prevent component rendering.
  • Avoid mutating arrays and objects used by calculations.
  • Measure performance before adding unnecessary optimizations.

📌 Key Points

  • useMemo memoizes the result of a calculation.
  • It accepts a calculation function and dependency array.
  • The memoized value can be reused when dependencies do not change.
  • It is useful for selected expensive calculations.
  • It can be used with arrays, objects, filtering, sorting, and derived data.
  • Every relevant changing value should be considered in the dependency array.
  • useMemo does not prevent the component from rendering.
  • Simple calculations usually do not require memoization.
  • useMemo returns a value, while useCallback memoizes a function.
  • Use memoization when it provides a meaningful performance benefit.

🧠 Quick Quiz

Question: What is the main purpose of the useMemo Hook?