Memoization in React using useMemo
and useCallback
How React works (in a nutshell)
You need to have a decent understand of how React works to understand the benefits of these hooks
The main thing that React does is keep our UI in sync with our application state. (through re-rendering)
Each re-render is a new snapshot of application UI (based on application state), or what the DOM should look like based on the current state
We don't directly tell React which DOM nodes to change, we tell React what the UI should look like based on state
useMemo
Basically allows us to cache a computed value
It has a list of dependencies used for the cache invalidation strategy, when component re-renders for other reasons other than the dependencies, ignore function and pass cached value
useCallback
Does the same thing as useMemo
but for functions instead of arrays and objects, really just syntactic sugar
Similar to arrays and objects, functions are compared by reference, not by value This means that if we define a function within our components, it'll be re-generated on every single render, producing an identical-but-unique function each time.
// This:
React.useCallback(function helloWorld() {}, []);
// ...Is functionally equivalent to this:
React.useMemo(() => function helloWorld() {}, []);
Additional Information
Memoization has computational costs, so it's not always worth it to memoize everything
You can memoize a result of specific computation, as well as the entire component to make it a pure component
A pure component is one that always produce the same output given the same input, and we can skip the re-renders where nothing's changed.
Sometimes you can avoid memoization by just restructuring/abstracting components by enforcing separation of concerns and single responsibility principle such that each component manages its own state, and would not cause unrelated components to re-render. (note that this is not always possible in a large, real-world application)