React Hook: useMemo()
useMemo() Hook
"useMemo" is a React Hook that lets you cache the result of a calculation between re-renders.
useMemo(calculateValue, dependencies)
parameters
- calculateValue: The function calculating the value that you want to cache. It should be pure, should take no arguments, and should return a value of any type.
- Dependencies: The list of all reactive values referred to inside of the calculateValue code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. The list of dependencies must have a constant number of items and be written inline like [dep1, dep2, dep3]. React will compare each dependency with its previous value using the "Object.is" comparison algorithm.
Returns
On the initial render, useMemo returns the result of calling calculateValue with no arguments. During subsequent renders, it will either return an already stored value from the last render if the dependencies haven't changed or call calculateValue again, and return the result that calculateValue has returned.
Caveats(Warning)
- useMemo is a hook, so you can use it at the top level of your component or your own hooks. You can't call it inside loops or conditions.
- In strict mode, React will call your calculation function twice in order to help you find accidental impurities. This is development-only behavior and does not affect production. The result from one of the calls will be ignored.
- React will not throw away the cached value unless there is a specific reason to do that. For example - in development, React throws away the cache when you edit the file of your component. Both in development and in production, React will throw away the cache if your component suspends during the initial mount.
Usage
Skipping expensive recalculations
To avoid expensive/unnecessary recalculations one can you useMemo to optimize the performance.
Optimizing with the useMemo is only valuable in a few cases:
- The calculation you're putting in useMemo is noticeably slow, and its dependencies rarely change.
- you pass it as a prop to a component wrapped in 'memo'. you want to skip re-rendering if the value hasn't changed. Memoization lets your component re-render only when dependencies aren't the same.
- The value you're passing is later used as a dependency of some Hook. For Example - maybe another useMemo calculation value depends on it. Or maybe you are depending on this value from useEffect.
In practice, you can make a lot of memoization unnecessary by following a few principles:
- when a component visually wraps other components, let it accept JSX as children. This way, when the wrapper component updates its own state, React knows that its children don't need to re-render.
- Prefer local state and don't lift state up any further than necessary.
- Keep your rendering logic pure.
- Avoid unnecessary effects that update state.
- Try to remove unnecessary dependencies from your effects.
Skipping re-rendering of components
In some cases, useMemo can help you optimize the performance of re-rendering child components.
Memoizing a dependency of another Hook
Memoizing a function
Similar to how "{ }" creates new object/different object, function declarations like "function(){ }" and expression like "() => { }" produce different function on every re-render.
Note: for memoizing a function React has a built-in hook specifically for that i.e. "useCallback".
The only benefit of useCallback is that it lets you avoid writing an extra nested function inside.
This is how we covered the React Hook: "useMemo". I hope you guys will have some clarity on this topic by going through this blog.
Any comments or suggestions are welcome!
My reference for this blog. You can read more here - https://beta.reactjs.org/reference/react/useMemo