# 16) useCallback Hook

1.  **<mark class="bg-yellow-200 dark:bg-yellow-500/30">useCallback</mark>**  
    `useCallback` is 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. `useCallback` helps **prevent unnecessary re-renders** by keeping the function reference stable.
    
    ```javascript
    const memoizedFunction = useCallback(() => {
      // logic
    }, [dependencies]);
    ```
    
    Returns a **cached version of the function**  
    Recreated **only when dependencies change**
    
2.  **<mark class="bg-yellow-200 dark:bg-yellow-500/30">Example</mark>**
    
    ```javascript
    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>
      );
    }
    ```
    
    `handleClick` is **not recreated on every render.**  
    Same function reference is reused.  
    Useful when passing to child components.
    
3.  **<mark class="bg-yellow-200 dark:bg-yellow-500/30">Key Characteristics</mark>**  
    i) Memoizes Function  
    Returns the same function reference across renders  
    ii) Dependency-Based  
    Function updates only when dependencies change  
    iii) Works with `React.memo`  
    Prevents child component re-renders
    
4.  **<mark class="bg-yellow-200 dark:bg-yellow-500/30">When to Use useCallback?</mark>**  
    Passing functions to child components  
    Optimizing performance with `React.memo`  
    Preventing unnecessary re-renders in large apps
    
5.  **<mark class="bg-yellow-200 dark:bg-yellow-500/30">Advantages of useCallback</mark>**  
    Improves performance - Avoids unnecessary re-renders.  
    Stable function reference - Important for optimized components.  
    Better control over rendering.  
    `useCallback` is 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.
    
6.  **<mark class="bg-yellow-200 dark:bg-yellow-500/30">useCallback vs useMemo</mark>**  
    i) useCallback - Memoizes function and Prevents new function reference  
    ii) useMemo - Memoizes value and Avoids expensive recalculation
    
7.  **<mark class="bg-yellow-200 dark:bg-yellow-500/30">Real life example of useCallback</mark>**  
    i) Without useCallback
    
    ```javascript
    const 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
    
    ```javascript
    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}
            />
          ))}
        </>
      );
    }
    ```
