1. Introduction
In this tutorial, we’ll discuss the useMemo
hook which plays important role in performance optimization of the application.
The React useMemo
hook lets you cache the result of a calculation between re-renders. You call useMemo
at the top level of your component to cache a calculation value between re-rendering of the component.
2. Signature
const cachedValue = useMemo(calculateValue, dependencies)
calculateValue
: This is the calculated value you want to cache between re-renders. This function is pure, takes no arguments and can return value of any type. Initially, the React calls the function with the given dependencies and cache the calculated value. During the next re-render, React does not call the function if the dependencies are not changed. If the dependencies are changed then the React will call the function and cache the values. This type of caching is called memoization.dependencies
: The list of all reactive values referenced inside of thecalculateValue
code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. React uses theObject.is
comparison to evaluate each dependency against its previous value.
3. Points to note about useMemo
- When calculation takes time to finish and can be reused in re-renders then
useMemo
is the right option to use.useMemo
is ideal if the dependencies do not change frequently. useMemo
should only be used for performance optimization and not to usually cache the values.useMemo
is a hook, so you can call it only at the top level of your component or your own hooks. You can’t calluseMemo
hook inside conditions or loops. If you have this requirement, then you should create a new component and move the state to it.- In Strict mode, React will call your calculation function twice. This helps in finding accidental impurities. The result from one of the calls will be ignored.
- React will not remove the cached value untill and unless there is specific reason. For example, in development the React throws away the value if the component file is changed. In production, the React throws away the cached value if your component suspends during the initial mount.
useMemo
does not speed up the initial render. Its benefit lies in avoiding redundant calculations during updates.
4. Example
Here is an example of useMemo
hook.
const ExpensiveComputationComponent = ({ num }) => { const expensiveComputation = (num) => { console.log('Performing expensive computation...'); let result = 0; for (let i = 0; i < 99999999; i++) { result += num; } return result; }; const memoizedValue = useMemo(() => expensiveComputation(num), [num]); return ( <div> <p>Result of the expensive computation: {memoizedValue}</p> </div> ); };
Here, expensiveComputation
is the expensive calculation function of which we want to cache the value and num
is the dependency.
useMemo
caches a calculation result between re-renders until its dependencies change. If the dependencies change, React recalculates the value using the dependencies and caches the calculated value. In our example, expensiveComputation
will re-run if the value of num
changes.
5. useMemo
can help in skipping re-rendering
If React encounters the identical JSX as in the previous render, it will skip re-rendering the component since JSX nodes are immutable. This means a JSX node object cannot change over time, allowing React to safely bypass a re-render. However, for React to recognize this, the node must be the exact same object, not just similar in appearance. This is where, useMemo
can help.
Consider the following example from a component.
const children = useMemo(() => <List items={someDependency} />, [someDependency]);
Here, List
will not re-render until someDependency
remains same.
6. Conclusion
In conclusion, the useMemo
hook in React is a powerful tool for optimizing performance by memoizing values and preventing unnecessary recalculations. By leveraging useMemo
, you can ensure that expensive computations are only performed when their dependencies change, leading to more efficient rendering and a smoother user experience. Remember that while useMemo
can help with performance, it should be used judiciously. Overuse or misuse can lead to unnecessary complexity in your code.