Quantum Tech Newz Logo
HomeWhat’s NewAIReactJS

Understanding useMemo() hooks: simplifying with its usecases and scenarios

When building modern React applications, performance optimization is key—especially when dealing with complex computations or large-scale UI components. One powerful but often misunderstood tool in the React ecosystem is the useMemo hook. This post will break down what useMemo is, when to use it, and provide a hands-on example to help you integrate it effectively into your applications.

What is useMemo?

useMemo is a React hook that boosts performance by caching the result of a function and recalculating it only when its dependencies are updated. This can help you avoid unnecessary recalculations, especially for expensive operations.

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

Here, computeExpensiveValue will only re-run if either a or b changes.

When Should You Use useMemo?

Many developers overuse useMemo, hoping for performance boosts that may never come. It's important to use it only when necessary—primarily when:

  • You have expensive computations.
  • Your component re-renders frequently.
  • Re-rendering leads to performance lags.
  • You want to avoid unnecessary re-rendering of child components.

Use Cases 1. Filtering or Sorting Large Datasets : When you have a large dataset, applying filters or sorting operations on every render can be expensive. To prevent this, useMemo can memoize the filtered or sorted result so that the operation only runs when necessary.

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

const largeUserList = Array.from({ length: 1000 }, (_, index) => ({
  id: index + 1,
  name: `User ${index + 1}`,
}));

const UserSearch = () => {
  const [searchTerm, setSearchTerm] = useState('');

  // Memoizing the filtered list to avoid re-filtering on every render
  const filteredUsers = useMemo(() => {
    console.log('Filtering users...');
    return largeUserList.filter(user =>
      user.name.toLowerCase().includes(searchTerm.toLowerCase())
    );
  }, [searchTerm]); // Only re-run when searchTerm changes

  return (
    <div>
      <input
        type="text"
        placeholder="Search users..."
        value={searchTerm}
        onChange={e => setSearchTerm(e.target.value)}
      />
      <ul>
        {filteredUsers.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

export default UserSearch;

Why useMemo Here?

Filtering happens only when the searchTerm changes, avoiding unnecessary filtering when the list is already computed. This saves CPU time when dealing with large datasets.

2. Avoiding Re-Renders of Pure Child Components : If a child component receives props that don’t change frequently, but are being recalculated on every render, it will cause unnecessary re-renders. useMemo helps by memoizing the props value.

Example: Passing Memoized Data to a Child Component

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

const ChildComponent = React.memo(({ filteredList }) => {
  console.log('Child re-rendered');
  return (
    <ul>
      {filteredList.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
});

const ParentComponent = () => {
  const [searchTerm, setSearchTerm] = useState('');

  const largeItemList = Array.from({ length: 500 }, (_, index) => ({
    id: index + 1,
    name: `Item ${index + 1}`,
  }));

  // Memoizing the filtered list to avoid re-filtering on every render
  const filteredItems = useMemo(() => {
    console.log('Filtering items...');
    return largeItemList.filter(item =>
      item.name.toLowerCase().includes(searchTerm.toLowerCase())
    );
  }, [searchTerm]);

  return (
    <div>
      <input
        type="text"
        placeholder="Search items..."
        value={searchTerm}
        onChange={e => setSearchTerm(e.target.value)}
      />
      <ChildComponent filteredList={filteredItems} />
    </div>
  );
};

export default ParentComponent;

Why useMemo Here?

  • We store the filteredItems using memoization, ensuring that the ChildComponent only updates when the searchTerm value changes.
  • The ChildComponent only receives the necessary data, and React can skip re-renders for pure components like ChildComponent that only depend on the props.

3. Heavy Calculations Based on Props or State : Some operations, like financial calculations, image processing, or data visualizations, may be expensive. Instead of recalculating on every render, memoizing these calculations ensures they run only when relevant props or state change.

Example: Complex Calculation for a Financial Report

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

const FinancialReport = ({ income, expenses }) => {
  // Heavy calculation for profit margin
  const profitMargin = useMemo(() => {
    console.log('Calculating profit margin...');
    return ((income - expenses) / income) * 100;
  }, [income, expenses]); // Only re-run when income or expenses change

  return (
    <div>
      <h2>Financial Report</h2>
      <p>Income: ${income}</p>
      <p>Expenses: ${expenses}</p>
      <p>Profit Margin: {profitMargin.toFixed(2)}%</p>
    </div>
  );
};

const App = () => {
  const [income, setIncome] = useState(100000);
  const [expenses, setExpenses] = useState(60000);

  return (
    <div>
      <FinancialReport income={income} expenses={expenses} />
      <button onClick={() => setIncome(income + 5000)}>Increase Income</button>
      <button onClick={() => setExpenses(expenses + 2000)}>Increase Expenses</button>
    </div>
  );
};

export default App;

When NOT to Use useMemo

  • For trivial computations. The overhead of memoization may actually slow things down.
  • As a blanket solution. Optimize only after identifying bottlenecks with profiling tools.
  • For non-expensive logic. If the function runs quickly, useMemo is unnecessary.

Conclusion : useMemo is a valuable optimization tool, but like all tools, it’s most effective when used appropriately. Understand your application's performance bottlenecks before reaching for it. Focus on memoizing expensive, repeatable operations that don't need to be recalculated every render.

By using useMemo thoughtfully, you can keep your React app fast, smooth, and efficient.


Sudhir Yadav, Senior Software Engineer