React useCallback Hook
25 April 2025 | Category: React Js
What is useCallback?
In simple terms:
useCallbackis a React Hook that memorizes a function, so it doesn’t get recreated on every render – unless its dependencies change.
This helps prevent unnecessary re-renders and improves performance when passing functions to child components.
📦 When to use useCallback
You’ll want to use useCallback when:
✅ You’re passing functions as props to child components
✅ Your component re-renders often and causes unnecessary updates
✅ You want to optimize performance in large React apps
🔧 Syntax
const memoizedFunction = useCallback(() => {
// function logic
}, [dependencies]);
- Returns a memoized version of the callback function
- Only changes if dependencies in the array change
📌 Real Life Analogy
Imagine you’re a chef and your helper asks for your signature sauce recipe every time you cook. Without useCallback, you rewrite it every time. With useCallback, you just save the recipe once and reuse it unless the ingredients change!
✅ Basic Example
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount((prev) => prev + 1);
}, []);
return (
<div>
<h2>Count: {count}</h2>
<button onClick={increment}>Increment</button>
</div>
);
}
🔍 Even though increment looks simple, useCallback ensures the function stays the same across renders unless dependencies change.
🤖 When useCallback Shines – Child Components
Let’s see how useCallback helps prevent unnecessary re-renders of child components.
✅ Without useCallback (inefficient)
function Child({ onClick }) {
console.log('Child rendered');
return <button onClick={onClick}>Click me</button>;
}
export default function App() {
const [count, setCount] = useState(0);
const handleClick = () => {
console.log('Clicked');
};
return (
<>
<button onClick={() => setCount(count + 1)}>Re-render Parent</button>
<Child onClick={handleClick} />
</>
);
}
Even when clicking the parent button, the child re-renders every time because handleClick is recreated on every render.
✅ With useCallback (optimized)
import React, { useState, useCallback } from 'react';
const Child = React.memo(({ onClick }) => {
console.log('Child rendered');
return <button onClick={onClick}>Click me</button>;
});
export default function App() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Clicked');
}, []);
return (
<>
<button onClick={() => setCount(count + 1)}>Re-render Parent</button>
<Child onClick={handleClick} />
</>
);
}
🔍 Now, the Child component won’t re-render unless handleClick actually changes (which it won’t, thanks to useCallback).
📋 Summary Table
| Concept | Description |
|---|---|
useCallback | Memoizes a function |
| Prevents | Recreating function on every render |
| Use case | When passing functions to memoized children |
| Dependencies | Function will update only when these change |
⚠️ Common Mistakes
- Overusing
useCallback: Don’t use it everywhere. Only when necessary (especially withReact.memo). - Missing dependencies: Always list the correct dependencies or use ESLint to warn you.
- Confusing with
useMemo:useMemo→ memoize a valueuseCallback→ memoize a function
🔥 Real World Use Cases
- Avoiding re-renders in
React.memochild components - Stable event handlers for optimized animations
- Efficient callbacks in custom hooks