useEffect.dev
← Back to lessons

Lesson 8. Optimizing performance with useMemo and useCallback 2. Memoize callbacks with useCallback

Let’s have a look at this other example:

Result

This component assumes it receives one prop: a value to display. Let’s suppose this value changes hundreds of times per second. It means that the callback we pass to the onClick attribute of the button will be recreated at each of those times. And creating functions in JavaScript can be CPU and memory-consuming when we make a hundred of them.

Another problem this might cause: here, we pass the callback to a button, but imagine that instead, we give it to a complex component hierarchy whose rendering is CPU consuming. Each time Comp is rendered, it creates a new callback, triggering a new rendering of the components using it—even if, from our perspective, it is still the same function (the same code, but a new reference).

We face the same problem as before: since the function doesn’t depend on value, we can create it once and for all with useMemo:

const onClick = useMemo(() => {
return () => console.log('clicked')
}, [])
// ...
<button onClick={onClick}>Click me!</button>

This pattern is so common for callback that React provides another hook for it, useCallback:

Result

The result is exactly the same: useCallback is just a shortcut, and it can be written very easilly using useMemo:

const useCallback = (fn, dependencies) => {
return useMemo(() => fn, dependencies)
}

It’s essential to know how to use useCallback because it is used widely in React projects. Developers often consider it a good practice to use it for all callbacks. But is it?

Should I use useCallback for all callbacks?

Short answer: no. Longer answer: don’t use useCallback unless you know that it will optimize performance because you measured it. In most cases, it won’t improve anything, and it might even make the performance worse.

Situations worth using useCallback often involve the memoization of components using React.memo, out of this guide’s scope.

Still, many projects use it, so there is one last pattern that I think is worth knowing, to have callbacks used in a list or table rows.