Your Page Title
🔍

    useCallback

    React provides a set of powerful hooks to manage state and side effects in functional components. One such hook is useCallback, which helps optimize performance in certain situations.

    What is useCallback?

    useCallback is a React Hook that returns a memoized version of a callback function. This means that React will remember the function you pass and only recreate it when its dependencies change.

    It’s commonly used to prevent unnecessary re-creation of functions, especially when passing them to child components or using them in dependencies.

    Syntax

    const memoizedCallback = useCallback(() => {
    // your function logic
    }, [dependencies]);
    • () => {}: This is your callback function.
    • [dependencies]: This is the dependency array. If any value here changes, the function will be re-created.

    Why Use useCallback?

    In React, every time a component renders, functions are re-created. This is usually fine, but in some cases, especially when:

    • A function is passed to a child component as a prop,
    • Or used inside an effect like useEffect or useMemo,

    …it can cause unnecessary re-renders or logic re-executions.

    useCallback helps avoid this by caching the function, so its reference stays the same unless it actually needs to change.


    Problem Without useCallback

    Here’s an example where a child component receives a function as a prop:

     function Parent() {
    const [count, setCount] = useState(0);

    const increment = () => setCount(count + 1);

    return <Child onClick={increment} />;
    }

    Every time Parent re-renders, the increment function is re-created. This causes the Child component to think the prop changed, even if it didn’t.


    Solution Using useCallback

    function Parent() {
    const [count, setCount] = useState(0);

    const increment = useCallback(() => {
    setCount((prev) => prev + 1);
    }, []);

    return <Child onClick={increment} />;
    }

    Now, increment has a stable reference. It only changes if the dependencies (in this case, none) change. So the Child component won’t re-render unnecessarily.


    Real-World Example with React.memo

     const Button = React.memo(({ onClick, label }) => {
    console.log("Rendering:", label);
    return <button onClick={onClick}>{label}</button>;
    });

    function App() {
    const [count, setCount] = useState(0);
    const [theme, setTheme] = useState("light");

    const increment = useCallback(() => {
    setCount((prev) => prev + 1);
    }, []);

    return (
    <>
    <Button onClick={increment} label="Increment" />
    <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
    Toggle Theme
    </button>
    <div>Count: {count}</div>
    </>
    );
    }

    Here, the Increment button won’t re-render when we toggle the theme, because increment is memoized with useCallback.


    When to Use useCallback

    Use useCallback only when needed — such as when:

    • You’re passing a callback to a memoized child component (React.memo).
    • The callback is used in a dependency array (like in useEffect, useMemo).

    Tip: Performance Consideration

    Using useCallback everywhere does not improve performance — in fact, it can hurt performance if overused because it also takes memory and processing to manage dependencies. Only use it when a function being re-created causes an issue.


    Conclusion

    useCallback is a helpful optimization tool in React that memoizes your functions and avoids unnecessary re-renders or executions. Use it wisely when you’re dealing with performance-sensitive components, especially when passing callbacks to children or inside dependency arrays.