linkedin Skip to Main Content
Just announced: We now support interviewing in spreadsheets!
Back to blog

A Guide To Using React’s useCallback() Hook

Development

Are you looking to optimize your React applications? Have you heard of the useCallback hook? useCallback is a powerful React hook that helps you optimize your application by preventing unnecessary re-renders. It can help you increase the performance of your React components, resulting in a better user experience. With useCallback, you can improve the performance of your React applications, ensuring users have a smooth and efficient experience. Read on to find out how you can use useCallback to get the most out of your React applications.

In this post, we review how to use React’s useCallback() hook. But for you to comfortably follow this guide, we first need to define referential equality and callback functions.

What Is Referential Equality?

Referential equality compares two variables pointing to the same object in memory. This is determined using the strict equality === operator in JavaScript.

On the other hand, structural equality is the comparison of two objects to see if they have the same value. This means that we consider two objects equal if they have the same properties and values, even if they are stored in different places in memory. This is determined using the loose equality == operator.

For example, the following two objects are equal in structure but not in reference:

const person = { name: "Doe" };

const anotherPerson = { name: "Doe" };

person === anotherPerson; // falseCode language: JavaScript (javascript)

Structural equality can only be true when both objects have the same content or values. Referential equality is more flexible—it only requires that both variables point to the exact memory location, even if they don’t have all the same content.

What Is a Callback Function in JavaScript?

A callback function is a function passed as an argument of another function. JavaScript executes the callback after the first JavaScript function executes. For example, let’s say you have a function that retrieves some data from a remote server. This operation could take some time to complete, and you don’t want your program to block or freeze while waiting for the data to be returned. Here, you could use a callback function to specify what should happen once you’ve retrieved the data. The callback function would be executed after the data has been successfully returned, allowing you to handle it and continue with the rest of your program.

import React, { useState, useEffect } from 'react';

function MyComponent(props) {

  const [data, setData] = useState(null);

  useEffect(() => {

    // Send a GET request to the server to retrieve the data

    fetch('/api/data')

      .then(response => response.json())

      .then(data => {

        setData(data);

        if (props.onDataLoaded) {

          // Invoke the callback function passed as a prop

          props.onDataLoaded(data);

        }

      });

  }, []);

  return (

    <div>

      {data ? <p>{data}</p> : <p>Loading data...</p>}

    </div>

  );

}Code language: JavaScript (javascript)

We often use callback functions to handle asynchronous events. For example, click events. A primary function could pass another function that handles a button click event as an argument. When you click the button, you trigger the callback function, which handles the click event.

What Is a useCallback() Hook?

A react useCallback hook is a callback that takes the components you want to optimize and a callback variable. JavaScript memoizes the variable for you and creates it on each render to remain the same. This eliminates the need to recalculate values unnecessarily.

The useCallback hook takes two arguments: a memoization function and an array of dependencies. When elements in the dependency array change, the memoized function is recreated.

You can use useCallback to control when things happen. One useful case is preventing idempotent mutations, such as rendering a component more than once in the same request.

How to Use useCallback() Hook

You can use the useCallback hook to memoize a function so that it is only recreated if one of the dependencies has changed. This is useful if you have a performance-intensive function that you call often. See the example below of how to use the useCallback hook with a functional component:

import {useState, useEffect} from 'react'


function App(){
    const [word,setWord]=useState("doe")
    const say = ()=>console.log(`Your word is: ${word})

    useEffect(()=>{
        say()
    },[say])
    return <div>Welcome!</div>
}
Code language: JavaScript (javascript)

In this example, the useEffect hook takes the say function as a dependency. This means that you should only call useEffect when the function changes. However, since react uses referential equality checks, the say function will evaluate to true upon every rerender, even when there’s no change. As such, the useEffect callback gets invoked on every render. This is not optimal for performance, and now we have to find a way to fix this.

One approach is to move the function to the useEffect block. This would solve the problem, but it’s not optimal because you couldn’t use that function anywhere else.

import {useState, useEffect}from 'react' 

function App({

    const [word,setWord]=useState("doe")

    const say = ()=> console.log(`Your word is: ${word}`)
    useEffect(()=>{ say() },
        [say]
    ) 
    return <div>Welcome!</div> 
}Code language: JavaScript (javascript)

The other option is to use the useCallback hook. To do this, wrap it around your say function. You should note that the useCallback function, like useEffect, takes a dependency as a second value. If your function accepts variables, you’ll pass them in the array; otherwise, you can leave it blank. For our case, since the function depends on the word, we’ll pass it.

import {useState, useEffect,useCallback} from 'react'

function App(){

    const [word,setWord]=useState("doe")

    const say = useCallback(()=>console.log(`Your word is: ${word}`),[word])

    useEffect(()=>{

        say() 

    },[say]) 

    return <div>Welcome!</div> 
}Code language: SAS (sas)

Best Practices to Follow When Using useCallback() Hook

  1. Only use useCallback when you actually need to memoize a function. Memoization can improve the performance of your application, but it comes at a cost in terms of added complexity and potential bugs. So, only use useCallback if you have a specific need for it.
  2. Pass a callback to useCallback as a reference, rather than defining it inline. This allows useCallback to track the dependencies of the callback and determine when it needs to be recreated.
  3. Be aware of your callback’s dependencies. When you pass a callback to useCallback, you also need to pass a list of its dependencies as the second argument. Ensure this list is accurate and up-to-date so that the callback is only recreated when necessary.
  4. Avoid passing expensive functions to useCallback. Because useCallback will only recreate the function when one of its dependencies has changed, it’s important to avoid passing expensive functions that may need to execute frequently. This can cause performance issues, as the function must be recreated and re-executed on every render.

When Should You Avoid Using useCallback() Hook?

You should not use the useCallback hook if you have no dependencies in your callback function. For example, if you have a callback function that only uses a prop from the parent component, you don’t need to use it.

const MyComponent = props => {

    const handleClick = () => {

    // write handleclick logic  
    };

    return (

        <div>

            <Button onClick={handleClick} />

        </div>

  );

};Code language: JavaScript (javascript)

In the above example, the handleClick function only uses handle click logic, which is passed in from the parent component. Since there are no dependencies in the handleClick function, you don’t need to use the useCallback hook.

React’s useCallback() Hook: Final Thoughts

This guide showed you how to use React useCallback to improve performance and avoid re-rendering issues. UseCallback allows you to memoize functions that are only recreated if one dependency or state has changed. This can be a useful optimization technique, particularly when working with expensive functions. However, only use it when necessary, and be aware that useCallback will prevent your function from garbage collection if the function is not being used. useCallback is a powerful tool that can improve performance in React applications but it should be used judiciously.

This post was written by Mercy Kibet. Mercy is a full-stack developer with a knack for learning and writing about new and intriguing tech stacks.