16) useCallback Hook
useCallback
useCallbackis a React hook used to memoize (cache) a function, so that the same function instance is reused between renders unless its dependencies change.
In React,
Every render recreates functions
New function reference → child components may re-render unnecessarily.useCallbackhelps prevent unnecessary re-renders by keeping the function reference stable.const memoizedFunction = useCallback(() => { // logic }, [dependencies]);Returns a cached version of the function
Recreated only when dependencies changeExample
import React, { useState, useCallback } from "react"; const Counter = () => { const [count, setCount] = useState(0); const handleClick = useCallback(() => { console.log("Button clicked"); }, []); return ( <div> <h2>{count}</h2> <button onClick={() => setCount(count + 1)}>Increment</button> <button onClick={handleClick}>Click Me</button> </div> ); }handleClickis not recreated on every render.
Same function reference is reused.
Useful when passing to child components.Key Characteristics
i) Memoizes Function
Returns the same function reference across renders
ii) Dependency-Based
Function updates only when dependencies change
iii) Works withReact.memo
Prevents child component re-rendersWhen to Use useCallback?
Passing functions to child components
Optimizing performance withReact.memo
Preventing unnecessary re-renders in large appsAdvantages of useCallback
Improves performance - Avoids unnecessary re-renders.
Stable function reference - Important for optimized components.
Better control over rendering.useCallbackis used to memoize a function so that it is not recreated on every render, helping prevent unnecessary re-renders when passing functions to child components.useCallback vs useMemo
i) useCallback - Memoizes function and Prevents new function reference
ii) useMemo - Memoizes value and Avoids expensive recalculationReal life example of useCallback
i) Without useCallbackconst ProductItem = React.memo(({ product, onAddToCart }) => { console.log("Rendered:", product.name); return ( <div> <h4>{product.name}</h4> <button onClick={() => onAddToCart(product)}> Add to Cart </button> </div> ); }); function ProductList({ products }) { const [cart, setCart] = React.useState([]); const [search, setSearch] = React.useState(""); const handleAddToCart = (product) => { setCart([...cart, product]); }; return ( <> <input onChange={(e) => setSearch(e.target.value)} /> {products.map(product => ( <ProductItem key={product.id} product={product} onAddToCart={handleAddToCart} /> ))} </> ); }ii) Using useCallback
function ProductList({ products }) { const [cart, setCart] = React.useState([]); const [search, setSearch] = React.useState(""); const handleAddToCart = React.useCallback((product) => { setCart(prev => [...prev, product]); }, []); return ( <> <input onChange={(e) => setSearch(e.target.value)} /> {products.map(product => ( <ProductItem key={product.id} product={product} onAddToCart={handleAddToCart} /> ))} </> ); }