Hello there, so we have almost covered the most used hooks in Reactjs. In my last post, we talked about the useRef
hook. In this post, we'll be covering the useCallback
hook. So let's start right away.
What is the useCallback hook
Use callback is a hook that returns a memoized callback function when one of the dependencies passed to it changes.
Wait! isn't that what useMemo does?
Well, the short answer is NO! Although both hooks are memoizing something they're however returning completely different things. The useMemo hook returns a memoized value while useCallback returns a memoized function
Why useCallbacks
?
The useCallback
hook is very useful when creating an application where some of the functions created are complex and re-rendering the component might make such function run which we don't want, probably because it might slow down the run time.
Let's see some actions
This hook accepts a callback function (useCallback) and a list of dependencies that makes the hook run when the value changes.
Basic usage
import { useCallback } from 'react';
const callbackVariable = useCallback(() => {
functionCall(a, b)
},[a, b]);
Example
You'd likely use the useCallback
hook alongside the useEffect
hook. Sometimes to prevent a continuous re-rendering or infinite loop. Consider the example in the sandbox below.
In the example above, I have 2 components I am working with, the App.js
file and the Score.js
file. The score component has a useEffect that is updating a state on props change and logging a message to the console.
import React, { useEffect, useState } from "react";
const Score = ({ score }) => {
const [showScore, setShowScore] = useState();
useEffect(() => {
setShowScore(score());
console.log("Component updating");
}, [score]);
return (
<div>
<div>Score here: {showScore}</div>
</div>
);
}
export default Score;
In the App.js
file, we have a clacScore
function that is adding 5 to any score the user enters, an input field that allows a user to enter a player name, and a button to toggle the player name. Everything seems to work fine, doesn't it?
There's a problem with our code. When we enter a player's name into our input field a message logs in the console and this also happens when we do anything at all on the page. This is a problem because we only want that message to display when we update the score.
useCallback to the rescue
Try replacing the clacScore
function with the code below.
const clacScore = useCallback(() => {
return(scoreEntered * 5);
}, [scoreEntered]);
Now try entering a player name into the input box or showing the player name. And notice that the message in the console only displays when we change the score. This is because we're using the useCallback
hook to tell React to only render the Score
component when the scoreEntered
state is being updated. So the hook has actually helped us boost the performance of our little application.
When should I useCallback?
So I'm sure we can agree that useCallback is awesome. However, that doesn't mean that we should start wrapping all our functions into a useCallback, remember that saying that goes:
Too much of everything isn't cool.
Yeah, that applies for useCallback
and useMemo
and useAnything
(wait! what?😅).
So the useCallback hook should only be used when
We want to do referential equality (because JavaScript sees a function as an object and we testing for equality between objects is quite a hassle in JavaScript)
When we have a complex function (i.e the computation of that function is costly).
Conclusion
Unrelated, but remember that one scene in justice league where they had to bring Superman back to life? they had a perfect reason to bring him back. The same logic applies here. Introducing useCallback means we're inviting some complexities already into our code, so we should have a perfect reason to useCallback in our code.
Thank you so much for reading. In the next section, we'll be covering the useReducer
hook. If you have any contributions or comments please drop them in the comment below. Also please follow me for more content like this and stay safe.
Top comments (5)
Amazing post! But If we put a log outside the useEffect hook, the
Score
component is still getting rendered every time we are entering some text in the player name input field which defeats the purpose of avoiding re-render unnecessarily. Why not usememo
along withuseCallback
?Fantastic post, and fantastic series. Really loved how you broke this information down.
Thank you Ash
Nice post! short and straight to the point! Good job :D
Thank you for this Amazing post! ❤