React js useCallback Hook Practice Questions with Solutions

Introduction

The useCallback Hook is used to cache a function between renders. This can be useful when a function is passed to a memoized child component and you want to avoid creating a new function reference when its dependencies have not changed. In this chapter, we will solve practical questions covering useCallback, dependencies, function references, child components, and performance optimization. React js useCallback Hook practice questions with solutions help to understand the concepts.

1. What is the useCallback Hook in React?

useCallback is a React Hook that lets you cache a function definition between renders.

Basic syntax:

import { useCallback } from "react";

const handleClick = useCallback(() => {
  console.log("Button clicked");
}, []);

React can reuse the same function reference between renders when the dependencies have not changed.

This can be useful when the function is passed to a memoized child component.


2. Why is useCallback used in React?

A component creates a new function reference when it renders.

For example:

const handleClick = () => {
  console.log("Clicked");
};

If the function is passed to a memoized child component, the new function reference can cause that child to render again.

useCallback can preserve the function reference:

const handleClick = useCallback(() => {
  console.log("Clicked");
}, []);

However, useCallback should not be used for every function. It is mainly useful when stable function identity provides a meaningful performance benefit.


3. How do you use useCallback in a React component?

Import useCallback from React and provide a function with its dependencies.

import { useCallback, useState } from "react";

function App() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    console.log("Count:", count);
  }, [count]);

  return (
    <div>
      <h2>{count}</h2>

      <button onClick={() => setCount(count + 1)}>
        Increase
      </button>

      <button onClick={handleClick}>
        Log Count
      </button>
    </div>
  );
}

export default App;

Here, handleClick depends on count.

When count changes, React creates a new function for the new value.


4. What is the difference between useMemo and useCallback?

Both Hooks are related to memoization, but they memoize different things.

useMemo

useMemo caches a calculated value.

const total = useMemo(() => {
  return price * quantity;
}, [price, quantity]);

useCallback

useCallback caches a function reference.

const handleClick = useCallback(() => {
  console.log("Clicked");
}, []);

A simple way to remember:

  • useMemo → memoizes a value
  • useCallback → memoizes a function

5. How do you use useCallback with a dependency?

You can add values used by the callback to its dependency array.

import { useCallback, useState } from "react";

function App() {
  const [name, setName] = useState("Ravi");

  const showName = useCallback(() => {
    console.log(name);
  }, [name]);

  return (
    <div>
      <h2>{name}</h2>

      <button onClick={() => setName("Amit")}>
        Change Name
      </button>

      <button onClick={showName}>
        Show Name
      </button>
    </div>
  );
}

export default App;

The callback uses name, so name is included in the dependency array.

When name changes, the callback is updated so that it uses the current value.


6. How does useCallback work with React.memo?

React.memo can skip re-rendering a component when its props have not changed.

However, a function prop created during the parent render can have a new reference each time.

Example:

const handleClick = () => {
  console.log("Clicked");
};

If this function is passed to a memoized child, the changed function reference can cause the child to render again.

Using useCallback:

const handleClick = useCallback(() => {
  console.log("Clicked");
}, []);

The function reference can remain stable between renders when its dependencies remain unchanged.

Example:

import { memo, useCallback, useState } from "react";

const Button = memo(function Button({ onClick }) {
  console.log("Button rendered");

  return <button onClick={onClick}>Click Me</button>;
});

function App() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    console.log("Button clicked");
  }, []);

  return (
    <div>
      <h2>Count: {count}</h2>

      <button onClick={() => setCount(count + 1)}>
        Increase
      </button>

      <Button onClick={handleClick} />
    </div>
  );
}

export default App;

Here, useCallback helps keep the onClick prop reference stable while count changes.


7. How do you use useCallback with a State Updater?

Sometimes a callback needs to update state based on the previous state.

In such cases, a functional state updater can reduce the callback’s dependencies.

Example:

import { useCallback, useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  const increase = useCallback(() => {
    setCount((previousCount) => previousCount + 1);
  }, []);

  return (
    <div>
      <h2>{count}</h2>

      <button onClick={increase}>
        Increase
      </button>
    </div>
  );
}

export default Counter;

The callback does not need to read count directly because the updater function receives the previous state.

Therefore, the dependency array can remain empty in this example.


8. Can useCallback be used with a List of Items?

Yes. useCallback can be useful when passing an action function to memoized list-item components.

Example:

import { memo, useCallback, useState } from "react";

const Product = memo(function Product({ product, onSelect }) {
  return (
    <button onClick={() => onSelect(product.id)}>
      {product.name}
    </button>
  );
});

function ProductList() {
  const [selectedId, setSelectedId] = useState(null);

  const products = [
    { id: 1, name: "Laptop" },
    { id: 2, name: "Mouse" },
    { id: 3, name: "Keyboard" },
  ];

  const selectProduct = useCallback((id) => {
    setSelectedId(id);
  }, []);

  return (
    <div>
      {products.map((product) => (
        <Product
          key={product.id}
          product={product}
          onSelect={selectProduct}
        />
      ))}

      <p>Selected Product ID: {selectedId}</p>
    </div>
  );
}

export default ProductList;

Here, the same selectProduct function reference can be passed to each memoized Product component.


9. What happens when a useCallback dependency changes?

When a dependency changes, React returns a new function reference for the callback.

Example:

const showUser = useCallback(() => {
  console.log(username);
}, [username]);

If username changes, the callback needs to use the new value, so React provides a new function reference.

If username remains unchanged, React can reuse the previous callback reference.

This is why dependencies are important when using useCallback.


10. Build a Practical Counter with a Memoized Child Component

Create a counter where a button component receives a callback from the parent.

Solution:

import { memo, useCallback, useState } from "react";

const CounterButton = memo(function CounterButton({ onIncrease }) {
  console.log("CounterButton rendered");

  return (
    <button onClick={onIncrease}>
      Increase Counter
    </button>
  );
});

function Counter() {
  const [count, setCount] = useState(0);
  const [theme, setTheme] = useState("Light");

  const increaseCounter = useCallback(() => {
    setCount((previousCount) => previousCount + 1);
  }, []);

  return (
    <div>
      <h1>Counter: {count}</h1>
      <p>Theme: {theme}</p>

      <CounterButton onIncrease={increaseCounter} />

      <button
        onClick={() =>
          setTheme((previousTheme) =>
            previousTheme === "Light" ? "Dark" : "Light"
          )
        }
      >
        Change Theme
      </button>
    </div>
  );
}

export default Counter;

How it works:

  • CounterButton is wrapped with memo.
  • increaseCounter is created using useCallback.
  • The callback uses the functional state updater.
  • Its dependency array can therefore remain empty.
  • Changing the theme does not change the increaseCounter function reference.
  • The memoized child can therefore skip a re-render when its other props remain unchanged.

This demonstrates a common performance optimization pattern involving useCallback and memo.

Key Takeaways

  • useCallback caches a function reference between renders.
  • It is mainly useful when stable function identity provides a performance benefit.
  • useCallback returns a function.
  • useMemo returns a memoized calculated value.
  • Dependencies determine when the callback needs a new function reference.
  • useCallback is often useful with React.memo.
  • A functional state updater can sometimes reduce the dependencies required by a callback.
  • useCallback does not automatically make an application faster.
  • It should not be added to every function without a reason.
  • Stable callbacks can be helpful when passing functions to memoized child components.
  • Correct dependencies are important so that callbacks use current reactive values.

FAQs

1. What is useCallback in React?

useCallback is a React Hook that caches a function reference between renders until its dependencies change.

2. Why is useCallback used?

It can help maintain a stable function reference, especially when passing callbacks to memoized child components.

3. Does useCallback prevent re-renders?

No. useCallback itself does not prevent component re-renders. It can help React.memo work effectively by keeping a function prop reference stable.

4. What is the difference between useMemo and useCallback?

useMemo memoizes a calculated value, while useCallback memoizes a function reference.

5. Can useCallback have dependencies?

Yes. Values used by the callback that need to stay synchronized should be included in its dependency array.

6. Should I use useCallback for every function?

No. useCallback is a performance optimization and should be used when stable function identity provides a meaningful benefit.

7. Can useCallback work with React.memo?

Yes. useCallback can provide a stable function prop that allows a memoized child component to skip re-rendering when its props are otherwise unchanged.

5. SEO Package

SEO Title: React.js useCallback Hook Practice Questions

Meta Description: React.js useCallback Hook Practice Questions with solved examples covering function memoization, dependencies, React.memo, and performance.

SEO Slug: react-js-usecallback-hook-practice-questions

Focus Keywords: React.js useCallback Hook, React useCallback, useCallback Hook Practice Questions, React useCallback Examples, useCallback Dependencies, React.memo useCallback, React Function Memoization, useMemo vs useCallback

Tags: React.js, React useCallback, useCallback Hook, React Hooks, React Hooks Practice Questions, useCallback Practice Questions, React useCallback Examples, React useCallback Tutorial, Function Memoization, React Function Memoization, useCallback Dependencies, React.memo, React.memo useCallback, React Performance, React Performance Optimization, useMemo vs useCallback, React State, React Function Components, Memoized Components, Stable Function Reference, React Callback Functions, React Coding Practice, React.js Examples, Learn React, React for Beginners, Frontend Development, Web Development, JavaScript, React Development

Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.

Scroll to Top