How to use useCallback in React
Using useCallback in React optimizes performance by memoizing functions, preventing unnecessary re-creation and reducing child component re-renders that depend on function props. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented useCallback in countless React components to optimize performance in complex dashboard interfaces and data-heavy applications. From my expertise, the most effective approach is wrapping event handlers and callback functions with useCallback and proper dependency arrays. This method provides significant performance improvements for components with expensive child renders or frequent updates.
Wrap functions with useCallback to prevent unnecessary re-creation and optimize child component performance.
import { useState, useCallback, memo } from 'react'
function ParentComponent() {
const [count, setCount] = useState(0)
const [users, setUsers] = useState([])
const handleIncrement = useCallback(() => {
setCount(prevCount => prevCount + 1)
}, [])
const handleUserUpdate = useCallback((userId, newData) => {
setUsers(prevUsers =>
prevUsers.map(user =>
user.id === userId ? { ...user, ...newData } : user
)
)
}, [])
const handleUserDelete = useCallback((userId) => {
setUsers(prevUsers => prevUsers.filter(user => user.id !== userId))
}, [])
return (
<div>
<p>Count: {count}</p>
<button onClick={handleIncrement}>Increment</button>
<UserList
users={users}
onUpdate={handleUserUpdate}
onDelete={handleUserDelete}
/>
</div>
)
}
const UserList = memo(({ users, onUpdate, onDelete }) => {
return (
<div>
{users.map(user => (
<UserItem
key={user.id}
user={user}
onUpdate={onUpdate}
onDelete={onDelete}
/>
))}
</div>
)
})
The useCallback hook takes a function and dependency array, returning a memoized version that only changes when dependencies change. This prevents child components from re-rendering unnecessarily when parent state updates don’t affect the callback functions. Use empty dependency arrays for functions that don’t rely on props or state.
Best Practice Note:
This is the same useCallback optimization pattern we use in CoreUI React components for performance-critical interfaces with complex interaction patterns.