Here's the basic syntax of useCallback
:
const memoizedCallback = useCallback(() => { // function logic }, [dependencies]);
memoizedCallback
: The memoized version of the function that only changes if the dependencies change.dependencies
: An array of dependencies that the function depends on. The function will only be re-created if one of these dependencies changes.Suppose you have a component that renders a list of items, and you want to pass a callback to each item. Without useCallback
, a new function is created on each render, which could cause unnecessary re-renders in child components.
Without useCallback
:
import React, { useState } from 'react'; function ParentComponent() { const [count, setCount] = useState(0); const handleClick = () => { console.log('Button clicked'); }; return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button> <ChildComponent onClick={handleClick} /> </div> ); } function ChildComponent({ onClick }) { console.log('ChildComponent re-rendered'); return <button onClick={onClick}>Click me</button>; } export default ParentComponent;
With useCallback
:
import React, { useState, useCallback } from 'react'; function ParentComponent() { const [count, setCount] = useState(0); const handleClick = useCallback(() => { console.log('Button clicked'); }, []); // Empty dependency array, so it won't change unless explicitly updated. return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button> <ChildComponent onClick={handleClick} /> </div> ); } function ChildComponent({ onClick }) { console.log('ChildComponent re-rendered'); return <button onClick={onClick}>Click me</button>; } export default ParentComponent;
useCallback
useEffect
.useCallback
useCallback
everywhere can complicate your code and won’t necessarily improve performance.useCallback
might outweigh its benefits.