React useCallback Hook
The useCallback
hook is used to memoize a function in React. It ensures that a function reference does not change unless its dependencies change. This is particularly useful when passing functions as props to child components, as it prevents unnecessary re-renders and optimises performance.
1. Basic Example: Avoiding Re-Creation of Functions using useCallback Hook
In this example, we use useCallback
to memoize a button click handler. Without useCallback
, the handler function would be recreated on every render, which could lead to performance issues in larger applications.
App.js
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []); // No dependencies, so function is memoized forever
return (
<div>
<h2>Count: {count}</h2>
<button onClick={increment}>Increment</button>
</div>
);
}
export default Counter;
Explanation:
useCallback
: Memoizes theincrement
function to prevent it from being recreated on every render.- The empty dependency array
[]
ensures that the function is created only once and reused thereafter. - This is useful for preventing performance issues when the function is passed as a prop to child components.
Output:
2. Example: Optimising Child Component Re-Renders using useCallback Hook
In this example, we demonstrate how useCallback
prevents unnecessary re-renders of child components by memoizing the functions passed as props. The child component will only re-render if the function reference changes.
App.js
import React, { useState, useCallback, memo } from 'react';
const Child = memo(({ onClick }) => {
console.log('Child rendered');
return <button onClick={onClick}>Click Me</button>;
});
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []); // Memoize the function
return (
<div>
<h2>Parent Count: {count}</h2>
<Child onClick={handleClick} />
</div>
);
}
export default Parent;
Explanation:
memo
: Wraps the child component to prevent unnecessary re-renders unless its props change.useCallback
: Ensures thehandleClick
function reference remains the same between renders.- The child component only re-renders when the
handleClick
function reference changes, optimizing performance.
Output:
3. Example: Dependency Management using useCallback Hook
In this example, we use dependencies in useCallback
to update the memoized function when certain state variables change. This ensures the function remains consistent with the latest state.
App.js
import React, { useState, useCallback } from 'react';
function Greeting() {
const [name, setName] = useState('');
const [greeting, setGreeting] = useState('');
const updateGreeting = useCallback(() => {
setGreeting(`Hello, ${name}!`);
}, [name]); // Dependency array includes 'name'
return (
<div>
<input
type="text"
value={name}
onChange={e => setName(e.target.value)}
placeholder="Enter your name"
/>
<button onClick={updateGreeting}>Update Greeting</button>
<p>{greeting}</p>
</div>
);
}
export default Greeting;
Explanation:
useCallback
: Memoizes theupdateGreeting
function and re-creates it only whenname
changes.- The dependency array ensures the function always uses the latest value of
name
. - This approach keeps the function optimized while ensuring it behaves correctly with updated state.
Output:
Conclusion
The useCallback
hook is a powerful tool for optimising performance in React applications. By memoizing functions, you can prevent unnecessary re-renders and improve the efficiency of components that rely on function props. Use useCallback
when passing functions as props or when a function depends on specific state variables.