Suggest an editImprove this articleRefine the answer for “When to use useCallback()?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)The `useCallback()` hook is needed **not to speed up a function**, but to **keep the same reference to a function** across renders. **Key point:** without a dependency array, `useCallback` recreates the function on every render, meaning no memoization actually happens.Shown above the full answer for quick recall.Answer (EN)Image## When to use `useCallback()` The `useCallback()` hook is needed **not to speed up a function**, but to **keep the same reference to a function** across renders. This matters when: 1. **The function is passed to a child component**, especially if it is wrapped in `React.memo`. 2. **The function is used in** `useEffect` **/** `useMemo` and must stay stable (so it does not trigger the effect again). 3. You want to avoid **unnecessary recreation of functions** on every render (which causes unnecessary re-renders). --- ### Example 1: passing a function to a `React.memo` component ```javascript const Button = React.memo(({ onClick }) => { console.log("Button re-render"); return <button onClick={onClick}>+</button>; }); function Counter() { const [count, setCount] = useState(0); // Without useCallback → a new function is created on every render const increment = useCallback(() => setCount(c => c + 1), []); return ( <div> <p>{count}</p> <Button onClick={increment} /> </div> ); } ``` Here: - `increment` is created **once**, since the dependencies are `[]`. - The button does not re-render without a reason. Without `useCallback`, `Button` would re-render on every change of `count`. --- ### Example 2: a stable dependency in `useEffect` ```javascript function FetchUser({ id }) { const fetchUser = useCallback(() => { return fetch(`/api/user/${id}`).then(res => res.json()); }, [id]); useEffect(() => { fetchUser(); }, [fetchUser]); // useEffect fires only when id changes } ``` Without `useCallback`, `fetchUser` would be recreated every render, and `useEffect` would fire **every time** - even if `id` had not changed. --- ## Summary - when it is actually worth using | Situation | Worth using? | Why | |---|---|---| | Passing a function to a `React.memo` component | Yes | Avoids unnecessary re-renders | | Using a function in `useEffect` / `useMemo` | Yes | Stabilizes the dependency | | Calling the function directly inside JSX | No | Pointless, it is not preserved | | The function does not depend on props or state | OK with `[]` | Created only once | | A lightweight function that does not affect others | No | The optimization is not worth it | --- ## What happens if you do not specify dependencies ```javascript const memoizedFn = useCallback(() => { doSomething(a, b); }); ``` **Without a dependency array**: - `useCallback` will recreate the function **on every render** - meaning **no memoization happens at all**. - This is equivalent to simply writing: ```javascript const memoizedFn = () => doSomething(a, b); ``` For `useCallback` to work, you need to pass dependencies that tell React **when the function should actually be updated**. --- ## Example with dependencies ```javascript const handleClick = useCallback(() => { console.log(count); }, [count]); ``` - The function is recreated **only** if `count` changed. - If you had not specified `[count]`, the function would always contain a "frozen" `count` from the first render. --- ## Important to remember | Rule | Explanation | |---|---| | `useCallback(fn, deps)` caches the function reference | The function is created anew only when the dependencies change | | If you skip the dependencies | The function is recreated on every render (memoization does not work) | | If you set `[]` | The function is created once at mount and never updated | | Specify every value used inside | Otherwise the closure will hold stale data | --- ## Summary | Question | Answer | |---|---| | When to use `useCallback()` | When you need a function to keep its reference across renders (React.memo, useEffect, useMemo) | | What happens without dependencies | The function is recreated every render - memoization does not work | | What happens with `[]` | The function is created once and never updated | | What it returns | The same function, but with a memoized reference |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.