useCallback and useMemo are both React Hooks that help optimize the performance of a React application by memoizing values. They both accept a function as an argument and return a memoized version of the function.
Here is a simplified explanation of the difference between the two:
useCallback
useCallback is a hook that returns a memoized callback. A callback is a function that is passed as an argument to another function. In the context of React, a callback is often used as an event handler or to pass data between components. The useCallback hook takes two arguments: a function and a dependency array. It will return a memoized version of the function that only changes if one of the dependencies has changed.
Here's an example of how you might use the useCallback hook:
In this example, the handleClick function is passed as an event handler to the button element. The useCallback hook ensures that the handleClick function is only re-created if the count prop changes. This can be useful if the ParentComponent is re-rendered frequently, as it can help to prevent the function from being unnecessarily re-created.
useMemo
useMemo is a hook that returns a memoized value. It takes two arguments: a function that returns a value and a dependency array. It will call the function and return its result only if one of the dependencies has changed.
Here's an example of how you might use the useMemo hook:
In this example, the processedData value is created by calling the function passed to useMemo. This function does some expensive processing with the data prop. The useMemo hook ensures that the processedData value is only re-computed if the data prop changes. This can be useful if the processing is time-consuming and you don't want it to be re-done unnecessarily.
Summary
To summarize, the main difference between useCallback and useMemo is the type of value they return. useCallback returns a memoized callback function, while useMemo returns a memoized value. Both hooks can be used to optimize the performance of your React components by avoiding unnecessary re-creations of functions or values.
Top comments (22)
In your first example,
handleClick
will get recreated each time you click the button. You may change it to this:Or Simply not use the hook. There's no reason to memoize this kind on function. 😉
Hook useCallback uses useMemo under the hood
Do we have any benchmarks on how much more "optimized" this really is? I can't imagine how much performance is lost between:
and
If it isn't negligible, it has to be pretty close to it. I'd suppose any latency from things like fetching and so on make stuff like this pretty close to irrelevant. Would love to hear anyone's insights or reports from real app world.
I think it's not just the recreation of the function that you would need to take into consideration but the fact that not memoizing functions you pass to other components can cause them to also re-render unnecessarily. If that said component is heavy then it also degrades performance.
Just my two cents ;)
But doesn't React already handle that anyway via props? If you're props to said component (or the component's own state) aren't changing, react isn't going to re-render anything
But if the parent changes without child's props changing?
I think it can help in this case.
@fullstackchris There is a misconception there in what you think isnt changing.
React checks referential integrity to determine if a property has changed/not.
for each render the function's reference will be changed. Therefore, each time the parent re-renders it will pass a new function to the sub component and this component will think the function is new and changed since last render.
When you wrap the function in useCallback then it only changes the reference of the function when the dependencies change
PS:
This is essentially what React does to check equality by default
Hi Chris. So the difference in performance between using useCallback and not using it in the example you provided is likely to be negligible. The primary benefit of useCallback is that it can help prevent unnecessary re-renders in certain situations by "memoizing" the callback function.
In your example, the callback function is only dependent on the setCount function, which is a constant value and will not change. In this case, useCallback is not necessary.
However, in more complex cases where the callback function depends on other state or props that may change, and the callback function is passed down as a prop to a child component, using useCallback can help prevent unnecessary re-renders and improve the performance of your application.
This is a simple example just made for comprehension, consider this optimization in a more complex event handler for example.
Awesome explanation! Thank you!
Great article!
It described the difference clearly, haha
Thank you
Thanks, glad you found this helpful! :)
Very clear explanation of the subtle difference between these two hooks. Nice one!
Thanks Gil :)
How did you get the processedData inside useMemo? Perhaps another example would have been better. Because you are returning the memoized function name declaration.
The comment he wrote just above the return statement for processedData states that it's just a placeholder for some code where you would take the inputted data var, do some processing on it, save the results in processedData, and then return that var. It would have been more clear if he gave that var a different name though, for the name to be different than the memoized function name.
Exactly!
Just another GPT article... Horrible...
Thanks for short and sweet explanation Ahmed, good content.
Thanks Rumen! Glad you found it useful :)