Suggest an editImprove this articleRefine the answer for “What does useCallback() do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`useCallback()`** is a function-memoization hook. It returns the same function (by reference) across renders, as long as the dependencies haven't changed. **Key point:** `useCallback` does not speed up the function itself, it only keeps the reference stable so that a memoized child component (`React.memo`) doesn't re-render because of a "new" function.Shown above the full answer for quick recall.Answer (EN)Image## What `useCallback()` does `useCallback()` is a **function-memoization hook**. It **returns the same function (by reference)** across renders, as long as the dependencies haven't changed. --- ### Syntax: ```javascript const memoizedCallback = useCallback(callback, [deps]); ``` - `callback` is the function you want to "remember". - `[deps]` is the array of dependencies this function relies on. --- ### Example without `useCallback` ```javascript function App() { const handleClick = () => console.log('click'); return <Button onClick={handleClick} />; } ``` Every time the `App` component re-renders, React **creates a new function** `handleClick`. Even if the logic inside hasn't changed, the **reference is different**. If `Button` is memoized (`React.memo`), React will think: > "The `onClick` prop changed (a new reference), I need to re-render the child." Result: `Button` gets an **unnecessary re-render**. --- ### With `useCallback` ```javascript function App() { const handleClick = useCallback(() => console.log('click'), []); return <Button onClick={handleClick} />; } ``` Now: - `handleClick` is created **once**; - On the next render, React **returns the same reference** (if the dependencies haven't changed); - For the memoized `React.memo` child component, the `onClick` prop **hasn't changed**; - -> **the child component doesn't re-render**. --- ## How it works "under the hood" React keeps the "old" version of the function in memory. On the next render: - It compares the dependencies `[deps]`; - If **nothing has changed**, it returns the **old function reference** from memory; - If at least one dependency changed, it creates a new function and remembers it. --- ## A visual example ```javascript function Parent() { const [count, setCount] = useState(0); const handleClick = useCallback(() => { console.log('clicked'); }, []); // empty dependencies -> the reference is stable console.log('Parent render'); return ( <> <Child onClick={handleClick} /> <button onClick={() => setCount(c => c + 1)}>+</button> </> ); } const Child = React.memo(({ onClick }) => { console.log('Child render'); return <button onClick={onClick}>Child</button>; }); ``` **Without** `useCallback`**:** ```javascript Parent render Child render Parent render Child render (unnecessary) ``` **With** `useCallback`**:** ```javascript Parent render Child render Parent render (Child does not re-render) ``` --- ## When `useCallback` really helps Use it if: 1. The callback is passed **into a memoized child component** (`React.memo`, `useMemo`, etc.); 2. The callback is part of the **dependencies of another** `useEffect` **/** `useMemo`, and you want to avoid false reruns. --- ## When `useCallback` is **not needed** - If the function is **used only inside** the component (not passed to children in JSX). - If the **child is not memoized** (no `React.memo`). - If the component **re-renders every time anyway** (for example, the parent has no optimization). > `useCallback` does not speed up the function's execution. > It only **keeps the reference stable**, so React doesn't think it's "new". --- ## Parallel with `useMemo` | Hook | What it caches | Returns | |---|---|---| | `useMemo(fn, deps)` | the result of a computation | **a value** | | `useCallback(fn, deps)` | the function itself | **a function** | An equivalence example: ```javascript useCallback(fn, deps) ≡ useMemo(() => fn, deps); ``` --- ## Frequent pitfalls in usage Wrong dependencies: If you don't add the dependencies, React will use **stale data** from the closure. ```javascript // the count dependency is missing -> stale closure const onClick = useCallback(() => console.log(count), []); ``` Correct: ```javascript const onClick = useCallback(() => console.log(count), [count]); ``` --- ## Summary | What `useCallback` does | How it helps | |---|---| | Caches the function across renders | Avoids needlessly creating new functions | | Returns the same reference if dependencies haven't changed | Props on child components don't "change" | | Works together with `React.memo` | Genuinely avoids re-rendering the child | | Doesn't speed up the code or reduce CPU load | Only stabilizes the reference |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.