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.



