DEV Community


Posted on

Understanding useCallback in react

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

Relief meme

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]);
Enter fullscreen mode Exit fullscreen mode

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(() => {
    console.log("Component updating");
  }, [score]);

  return (
      <div>Score here: {showScore}</div>

export default Score;
Enter fullscreen mode Exit fullscreen mode

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]);
Enter fullscreen mode Exit fullscreen mode

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).


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)

apoorva2404 profile image
Apoorva Sharma • Edited

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 use memo along with useCallback?

ash_bergs profile image

Fantastic post, and fantastic series. Really loved how you broke this information down.

ilizette profile image

Thank you Ash

fabianpernia profile image
Fabián Pernía

Nice post! short and straight to the point! Good job :D

just_vkp profile image

Thank you for this Amazing post! ❤