- React Tutorial
- React Home
- React Setup
- React Introduction
- React ES6
- React Render HTML
- React JSX
- React Components
- React Class
- React Props
- React Events
- React Conditional
- React Lists
- React Forms
- React Router
- React Memo
- React CSS Styling
- React Hooks
- What is a Hook?
- React useState
- React useEffect
- React useContext
- React useRef
- React useReducer
- React useCallback
- React useMemo
- React Custom Hooks
React useMemo Hook
- useMemo is a built-in React hook designed to "memoize" (cache) the result of a calculation between re-renders.
- In standard React behavior, every variable inside a component is recalculated every time the component renders.
useMemoallows you to skip those expensive calculations if the inputs haven't changed.
Developer Tip: Think of
useMemo as a small piece of memory. React will store the output of a function and only re-run that function if one of the dependencies in the array has changed.
Purpose
- Performance Optimization: It prevents CPU-intensive functions from running on every single render, which is crucial for maintaining a smooth 60fps UI.
- Referential Equality: It helps maintain the same object reference between renders. This is vital when passing objects or arrays as props to child components wrapped in
React.memo. - Efficiency: It ensures that logic like complex data filtering, sorting, or large-scale transformations only happens when necessary.
Best Practice: Don't use
useMemo for every single variable. Memoization has its own overhead (memory usage and dependency comparisons). Only use it for truly "expensive" operations or to solve referential equality issues.
Syntax
- Import useMemo from the 'react' library.
- The hook takes two arguments: a create function (which returns the value to be cached) and a dependency array.
import React, { useMemo } from 'react';
// Syntax: const value = useMemo(callbackFunction, [dependencies]);
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Watch Out: If you provide an empty dependency array
[], the value will be calculated once on the initial render and never again. If you provide no array at all, it will recalculate on every render, defeating the purpose of the hook.
Memoized Value
- Use useMemo when you have a function that processes data—like filtering a large list—that shouldn't run again just because a different, unrelated state (like a timer or a toggle) updated.
import React, { useState, useMemo } from 'react';
const MemoizedValueExample = () => {
const [count, setCount] = useState(0);
const [items] = useState(['Apple', 'Banana', 'Orange', 'Grape', 'Pineapple']);
// We only want to filter this list if 'items' changes,
// not every time 'count' is incremented.
const expensiveSearch = useMemo(() => {
return computeExpensiveValue(items);
}, [items]);
return (
<div>
<h2>Example: Memoized Value</h2>
<p>Count (unrelated state): {count}</p>
<p>Computed Value: {expensiveSearch}</p>
<button onClick={() => setCount(c => c + 1)}>Re-render Component</button>
</div>
);
};
const computeExpensiveValue = (data) => {
// Imagine a heavy loop or complex math here
console.log('Running heavy calculation...');
return data.join(', ').toUpperCase();
};
Common Mistake: Calling
useMemo inside a loop or a conditional statement. Like all React Hooks, it must be called at the top level of your component.
Memoized Component
- While
React.memois the standard way to prevent component re-renders, useMemo can be used to memoize a specific piece of the UI (a JSX element) directly within a parent component.
import React, { useState, useMemo } from 'react';
// A component that takes time to render
const ExpensiveComponent = ({ value }) => {
console.log('Rendering ExpensiveComponent...');
return <div>Computed Result: {value}</div>;
};
const MemoizedComponentExample = () => {
const [count, setCount] = useState(0);
const [otherState, setOtherState] = useState(false);
// This component will ONLY re-render if 'count' changes.
// Clicking the "Toggle Other State" button won't trigger a re-render here.
const memoizedChild = useMemo(() => {
return <ExpensiveComponent value={count * 10} />;
}, [count]);
return (
<div>
<h2>Example: Memoized Component</h2>
{memoizedChild}
<button onClick={() => setCount(c => c + 1)}>Change Count</button>
<button onClick={() => setOtherState(!otherState)}>Toggle Other State</button>
<p>Other State: {otherState.toString()}</p>
</div>
);
};
Developer Tip: Use the React DevTools "Highlight updates when components render" feature to see exactly when your memoization is working (or failing).
Summary
The useMemo hook is a powerful tool for optimizing React applications. By caching the results of expensive function calls, you ensure that your app remains responsive and efficient. Use it when performing heavy data transformations or when you need to maintain referential integrity for objects and arrays passed to optimized child components.
Best Practice: Always start by writing clean, readable code without
useMemo. Only add memoization once you identify a specific performance bottleneck. Premature optimization can make code harder to maintain.