React

useMemo

Because functional components are functions, when re-rendering, all the codes inside the components will be executed again. This will make any variables in the scope will be re-defined or if you have any expensive calculations, they will also re-computed. Which will cause some lagging in the app. That's why useMemo is here to help, useMemo will return a memoized value and only recompute the value when one of the dependencies has changed.

useMemo has 2 arguments:

  • functionReturnValue: a function that computes some expensive calculations on rendering phases and returns the result as a memoized value.
  • arrayDependencies(Optional): a list of dependencies variables which if there are any changes in these, useMemo will call the functionReturnValue again to memorize a new value.
// Call signature
const memoizedValue = useMemo(functionReturnValue, arrayDependencies)

Note

You may find that useMemo is quite similar to useEffect, but they are used in different use cases. useEffect is called when a dependency has changed after the rendering is done, that's why they're called side effects. useMemo on the other hand, is called during the rendering is happening, and they also return a memoized value.


Basic Usage

Check out the example below for basic usage

function Count() {
const [count, setCount] = useState(0)
const [by2, setBy2] = useState(false)
// Computed only if count has changed
const computed1 = useMemo(() => {
const now = Date.now()
return now + count
}, [count])
// Computed on every render
const computed2 = useMemo(() => {
const now = Date.now()
return now + count
})
const now = Date.now()
// useMemo without any depenencies is just the same as this
const computed3 = now + count
return (
<>
<div>Current count is {count}</div>
<div>Current computed1 is {computed1}</div>
<div>Current computed2 is {computed2}</div>
<div>Current computed3 is {computed3}</div>
<div>
<input
type="checkbox"
onChange={(e) => setBy2(e.target.checked)}
/>
{' '}
By 2 (Check this will cause computed2 and 3 changed)
</div>
<Button
onClick={() => setCount(c => c + (by2 ? 2 : 1))}
>
+ {by2 ? 2 : 1}
</Button>
</>
)
}

You should know

Besides useMemo, React also has a High Order Component called React.memo that does the same functionality but at Component-level. You can check out Official React.memo Document for more information.

Previous
useLayoutEffect