How to Use useCallback in React

As the creator of CoreUI and with over 11 years of React development experience, I’ll demonstrate how to use the useCallback hook to optimize function references and component performance.

The useCallback hook memoizes function references, preventing child components from re-rendering when the function hasn’t actually changed.

import React, { useState, useCallback, memo } from 'react'

// Child component wrapped with memo for optimization
const ChildComponent = memo(({ onButtonClick, title }) => {
  console.log('ChildComponent rendered')
  return (
    <div>
      <h3>{title}</h3>
      <button onClick={onButtonClick}>Click me</button>
    </div>
  )
})

function ParentComponent() {
  const [count, setCount] = useState(0)
  const [name, setName] = useState('John')

  // Without useCallback, this function is recreated on every render
  const handleButtonClick = useCallback(() => {
    console.log('Button clicked!')
    setCount(prevCount => prevCount + 1)
  }, []) // Empty dependency array since we use functional update

  // Function that depends on state
  const handleNameChange = useCallback((newName) => {
    setName(newName)
  }, [])

  // Function with dependencies
  const createMessage = useCallback(() => {
    return `Hello ${name}, count is ${count}`
  }, [name, count])

  return (
    <div>
      <p>Count: {count}</p>
      <input
        value={name}
        onChange={(e) => handleNameChange(e.target.value)}
      />
      <p>{createMessage()}</p>
      <ChildComponent
        onButtonClick={handleButtonClick}
        title="Optimized Component"
      />
    </div>
  )
}

The useCallback hook takes a function and a dependency array, returning a memoized version that only changes when dependencies change. Use useCallback when passing functions to memoized child components, creating event handlers in loops, or when functions are dependencies for other hooks. The dependency array should include all values from component scope that the function uses.

Best Practice Note:

In CoreUI components, we use useCallback extensively for event handlers and callback props to prevent unnecessary re-renders of complex UI components. This is especially important in data tables, forms, and interactive components where performance optimization directly impacts user experience.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
Mastering JavaScript List Comprehension: The Ultimate Guide
Mastering JavaScript List Comprehension: The Ultimate Guide

How to Merge Objects in JavaScript
How to Merge Objects in JavaScript

How to Migrate from create-react-app to Vite?
How to Migrate from create-react-app to Vite?

How to sleep in Javascript
How to sleep in Javascript

Answers by CoreUI Core Team