Beginner's Guide to React useCallback Hook
Learn about the useCallback Hook, its use cases and implementation.
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the Beginner's Guide to Real World React course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Beginner's Guide to Real World React, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

[00:00 - 00:31] Lesson 6. The use callback hook. In a similar fashion to the use memo hook, use callback gives us a means to optimize our application somewhat. It also provides a form of memorization. However, the big difference between the two hooks is that use memo provides a way to memorize a value whilst use callback memorizes a function. It looks and feels almost identical to the implementation of use memo 2. You define and use use callback hook like this. Great, you're thinking. But why would anyone want to memorize a callback function?
[00:32 - 01:17] Well, the complicated answer is it depends. Let's start with a little one-on- one on react components. Each time a component rerenders, React will create a new version of items like function objects. Take the following code snippet as an example. Each time my epic component rerenders, the handle button click is recreated as a brand new function object. For most components, this isn't a problem and usually nothing that you need to concern yourself with . This recreating of functions is inexpensive and not going to cause you any problems, performance based or otherwise. However, there are some situations you might face when you don't want this behavior. One such example might be when the function is a dependency of other hooks. In this situation, you'd want to have access to the same function object across different renderings and not a brand new instance.
[01:18 - 01:44] I would be back to the infinite looping territory again. When it comes to the use callback hook, in essence, given the same dependency values, use callback returns the same function instance between rerenders. You can discover more on the use callback hook at the official React Docs website. Once you've checked those out, I'd recommend the following articles. Dimitri Pavlutin's guide to use callback, when to use use callback by a head creative and an article from kenzi.
[01:45 - 02:29] The use callback hook is one of those tools that you may or may not come across a great deal, but when you do need to use it, the benefits are great. However, because of the rather infrequent need to use this hook, our example this time is going to be a little more contrived to highlight those benefits. We'll be building a message generator and some buttons that increment counters within the component. We'll keep track of the functions that our component recreates across each rerender so you can see how use callback comes into play. Let's start by opening the use callback example.jsx file and building it out. So first things first, we'll need to import react, use state and of course the use callback hook. Next, we'll need a couple of constants that will live outside of our main components.
[02:30 - 03:14] We have a simple array of string messages that we'll use within our component, and with function star, we're creating a shiny new instance of a set object. You can store lists or collections of anything you like in a set object, but the key part here is that set naturally keeps things unique for us. The importance of this will become apparent in a little while. Next, let's create the default export component as we've started with in the previous lessons. As I'm sure you're becoming familiar with by now, let's outline a couple of variables at the top of our new component. We've got two state variables, counter and message. Our counter variable will hold the current count as we increase it, and while message will hold the currently selected message from our previously defined array of message strings .
[03:15 - 03:32] Now for the use callback part. We'll create three click handling functions here , one to increase the count, another to decrease it and the last one to generate a new message. Each will update one of the state variables we've just created.
[03:33 - 04:38] Both increase, counter and decrease counter implement the use callback hook using the counter variable as a dependency. Remember each time a dependency changes use callback will generate a new callback function object for us. Both these functions update the count value instead, either by adding one or removing one. The generate random message function depends on the message state variable and updates this message instead, pulling a random string from our messages array. The very last thing we'd like to do here before moving on with the JSX is to add these new functions into the function star, like so. Now each time our component re renders, it will attempt to add each of our three click handler functions into the function star set. If one of the function objects already exists within the set, it won't be added. Later on, we'll extract the number of functions in the set to see how many new function objects have been created on each re render.
[04:39 - 04:54] With our logic in place, all that remains is to outline the JSX for our UI. We're starting off by outputting the current count using the count value from state.
[04:55 - 05:24] Next we do the same but for message using the double pipe operator shortcut to display an instructional string should message be empty. Next we have three buttons that we're attaching to our click handlers, one to increase the counter, one to decrease it and a final one to trigger a message generation. The final piece of the JSX puzzle is to output a simple message to the user showing the number of items in the function star set. To do that, we call sets. size property, which is equivalent to an array's dot length property. Ready to see an action?
[05:25 - 05:57] Let's head over to the terminal and fire up the yarn start command opening the project in the browser once it's built. So you can see what we've got is quite simple. The current count is zero when we have no message set and our buttons are ready to be clicked. But take a look at the line under the HR element that counts the number of functions the component has created. You can see that our three click handler functions have been created and added into the set so the size of the set is naturally three.
[05:58 - 08:02] So what happens if we click one of the buttons? Let's click generate message to choose a random value from the messages array. Notice that even though the component has re- rendered only one additional function has been created. In this case, it was the generate random message click handler function and that's because its value instead, i.e. the message, changed. This state value is passed as a dependency to the use callback hook, hence the function is recre ated. This time, let's click on the counter plus and see what happens. Notice that this time the size of the function star jumps up from four to six. On this re-render, generate random messages kept the same because we haven't changed its dependency message. However, we've altered the count state variable, which both increase counter and decrease counter depend on. Therefore, both of these functions have been re-rendered and recreated on this particular rendering. But what happens without use callback? To drive the point home about the effective use callback, let's make a couple of changes to the component. Back in the component file, find our click handling tree or functions and remove the use callback hooks. So all we've done is remove the use callback hooks wrapper and the dependency array on the other end, leaving as with standard arrow functions. Refresh the browser and let's go through our button clicks once more. Notice this time that no matter what we click, the size of function star increases by three each time. Because our click handling functions are no longer memorized via the use callback hook, each time the component re-renders, a brand new version of them is created and added into the set object. As you can see, this has almost zero impact on the running app and our users will be none the wiser for our changes either way . However, it illustrates quite nicely exactly how the use callback hook works. That's everything wrapped up in this bumper module on diving deep into React hooks. In the next module, we'll be looking at navigation within React projects.