[{"data":1,"prerenderedAt":123},["ShallowReactive",2],{"qa-\u002Freact\u002Fhooks\u002Fusecallback-usememo":3},{"page":4,"siblings":95,"blog":120},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"questionsCount":85,"related":86,"seo":87,"seoDescription":88,"stem":89,"subtopic":90,"topic":91,"topicSlug":92,"updated":93,"__hash__":94},"qa\u002Freact\u002Fhooks\u002Fusecallback-usememo.md","Usecallback Usememo",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"hard","md","React","react",{},true,5,"\u002Freact\u002Fhooks\u002Fusecallback-usememo",[23,28,32,37,41,45,49,53,57,61,65,69,73,77,81],{"id":24,"difficulty":25,"q":26,"a":27},"what-is-usecallback","easy","What does useCallback do?","`useCallback` returns a **memoized version of a function** that only changes when\none of its dependencies changes. Calling it with the same dependencies returns the\nexact same function reference across renders.\n\n```jsx\nconst handleClick = useCallback(() => {\n  doSomething(id)\n}, [id]) \u002F\u002F new function only when `id` changes\n```\n\nWithout `useCallback`, a new function is created on every render. With it, the\nreference stays stable until `id` changes — which matters when passing the\nfunction to a memoized child or an effect dependency.\n\n**Rule of thumb:** `useCallback(fn, deps)` is `useMemo(() => fn, deps)`.\n",{"id":29,"difficulty":25,"q":30,"a":31},"what-is-usememo","What does useMemo do?","`useMemo` caches the **return value** of a computation and recomputes it only when\nits dependencies change.\n\n```jsx\nconst sorted = useMemo(\n  () => [...items].sort(compare),\n  [items] \u002F\u002F recompute only when items changes\n)\n```\n\nOn renders where `items` hasn't changed, React skips calling the sort and returns\nthe cached result. Use it for expensive derivations from props or state.\n",{"id":33,"difficulty":34,"q":35,"a":36},"callback-vs-memo","medium","What is the difference between useCallback and useMemo?","They solve the same problem — referential stability across renders — for different\noutput types:\n\n- `useMemo` memoizes the **return value** of a function (any value).\n- `useCallback` memoizes the **function itself** (a specific case of useMemo).\n\n```jsx\n\u002F\u002F these two are equivalent\nconst fn = useCallback(() => compute(x), [x])\nconst fn = useMemo(() => () => compute(x), [x])\n\n\u002F\u002F useMemo for a computed value\nconst result = useMemo(() => compute(x), [x])\n\u002F\u002F useCallback for a stable function reference\nconst handler = useCallback(() => post(x), [x])\n```\n\nIn practice: `useCallback` for functions, `useMemo` for values.\n",{"id":38,"difficulty":34,"q":39,"a":40},"referential-equality","What is referential equality and why does it matter for memoization?","JavaScript compares objects and functions by **reference** (memory address), not\nby content. Two identically-written functions are **not equal** unless they're\nthe same reference.\n\n```jsx\n(() => {}) === (() => {})  \u002F\u002F false — different references\nconst fn = () => {}\nfn === fn                  \u002F\u002F true — same reference\n```\n\nThis is why a new function created each render makes a child re-render even when\nnothing logically changed: `React.memo` sees a new prop reference and treats it\nas a change. `useCallback` returns the same reference, keeping memoization intact.\n",{"id":42,"difficulty":34,"q":43,"a":44},"react-memo-interaction","How do useCallback and React.memo work together?","`React.memo` wraps a component and skips re-rendering when all its props are\n**reference-equal** to the last render. If you pass an unstable function prop\n(new reference each render), `React.memo` still re-renders — defeating the memo.\n\n```jsx\nconst Button = React.memo(function Button({ onClick }) {\n  return \u003Cbutton onClick={onClick}>click\u003C\u002Fbutton>\n})\n\nfunction Parent() {\n  \u002F\u002F new function each render -> Button re-renders despite memo\n  return \u003CButton onClick={() => console.log('hi')} \u002F>\n\n  \u002F\u002F stable function -> memo works\n  const handleClick = useCallback(() => console.log('hi'), [])\n  return \u003CButton onClick={handleClick} \u002F>\n}\n```\n\nThe pattern: `React.memo` on the child + `useCallback` on the function prop\npassed from the parent.\n",{"id":46,"difficulty":14,"q":47,"a":48},"when-to-memoize","When should you actually use useMemo or useCallback?","Memoize when you have a **measurable performance problem**, not preemptively. The\nthree cases worth memoizing:\n\n1. **Expensive computation** — sorting\u002Ffiltering thousands of items, complex math.\n2. **Stable reference for a memoized child** — `React.memo` child that receives\n   functions or objects as props.\n3. **Effect dependency stabilization** — an object\u002Ffunction listed in `useEffect`\n   deps that would otherwise re-run the effect every render.\n\n```jsx\n\u002F\u002F worth it: sort runs O(n log n) on a large list\nconst sorted = useMemo(() => items.sort(compare), [items])\n\n\u002F\u002F not worth it: trivial, memo overhead exceeds savings\nconst doubled = useMemo(() => x * 2, [x])\n```\n\nProfile first. Every `useMemo`\u002F`useCallback` adds its own comparison cost and\ncognitive overhead — it's not free.\n",{"id":50,"difficulty":34,"q":51,"a":52},"premature-memoization","Why is premature memoization harmful?","`useMemo` and `useCallback` have their own cost: React must store the cached\nvalue, compare dependency arrays on each render, and manage garbage collection.\nMemoizing cheap operations can make performance *worse* because the overhead\nexceeds the computation.\n\n```jsx\n\u002F\u002F overhead > savings for trivial computation\nconst label = useMemo(() => `Hello ${name}`, [name])\n\u002F\u002F just compute it: const label = `Hello ${name}`\n```\n\nAdditionally, memoization adds cognitive load — developers reading the code must\nreason about whether the deps array is correct. Default to plain computation;\nadd memoization only when profiling shows a real problem.\n",{"id":54,"difficulty":14,"q":55,"a":56},"missing-deps","What happens if you omit a dependency from useMemo or useCallback?","The memoized value\u002Ffunction **closes over a stale value** — the one from the\nrender where it was last created. It never sees later updates to the omitted dep.\n\n```jsx\n\u002F\u002F user is omitted from deps -> greeting always shows the initial user.name\nconst greeting = useMemo(() => `Hi ${user.name}`, []) \u002F\u002F stale closure!\n\n\u002F\u002F correct\nconst greeting = useMemo(() => `Hi ${user.name}`, [user.name])\n```\n\nThe `react-hooks\u002Fexhaustive-deps` eslint rule catches this. Never suppress it to\n\"cache something forever\" — use a `useRef` if you intentionally want a value\nfrozen after mount.\n",{"id":58,"difficulty":14,"q":59,"a":60},"effect-dep-stability","How does useCallback help stabilize effect dependencies?","A function defined in a component is recreated each render (new reference). If\nan effect depends on it, the effect re-runs every render. `useCallback` gives the\nfunction a stable reference that only changes when its own deps do.\n\n```jsx\n\u002F\u002F without useCallback: new function each render -> effect fires every render\nfunction fetchUser() { return api.get(userId) }\nuseEffect(() => { fetchUser().then(setUser) }, [fetchUser])\n\n\u002F\u002F with useCallback: stable function -> effect fires only when userId changes\nconst fetchUser = useCallback(() => api.get(userId), [userId])\nuseEffect(() => { fetchUser().then(setUser) }, [fetchUser])\n```\n\nAlternatively, move the function inside the effect to remove the dependency\nentirely — that's often cleaner.\n",{"id":62,"difficulty":34,"q":63,"a":64},"object-stability-usememo","How do you stabilize an object prop with useMemo?","Wrap the object in `useMemo` so it keeps the same reference until its inputs\nchange. Without it, every render creates a new object even if the content is\nidentical — causing memoized children and dependent effects to fire.\n\n```jsx\n\u002F\u002F new object every render -> child always re-renders\n\u003CChart options={{ color: theme, size }} \u002F>\n\n\u002F\u002F stable reference -> child only re-renders when theme or size change\nconst options = useMemo(() => ({ color: theme, size }), [theme, size])\n\u003CChart options={options} \u002F>\n```\n\nThis is the object-version of `useCallback`. Prefer depending on the individual\nprimitives directly when possible — it's simpler.\n",{"id":66,"difficulty":34,"q":67,"a":68},"memo-expensive-calc","How do you memoize an expensive derived list?","Compute the derived value with `useMemo`, depending on the raw data and any sort\u002F\nfilter parameters. The computation is skipped on renders where none of those\ninputs changed.\n\n```jsx\nconst filtered = useMemo(\n  () => products\n    .filter(p => p.category === activeCategory)\n    .sort((a, b) => a.price - b.price),\n  [products, activeCategory]\n)\n```\n\nWithout `useMemo`, the filter and sort run on every keystroke, click, and hover\nthat triggers a re-render — even when `products` and `activeCategory` haven't\nchanged.\n",{"id":70,"difficulty":14,"q":71,"a":72},"usecallback-cost","What is the overhead of useCallback and useMemo?","Each call to `useCallback`\u002F`useMemo` on every render:\n1. Reads the stored deps array.\n2. Compares each dep with `Object.is`.\n3. Either returns the cached value or re-runs the computation.\n\nFor a tiny list or a trivial function, this comparison can cost **more** than just\nre-running the computation. React's own team has noted that memoization is a\nmicro-optimization and can be counter-productive on small values.\n\n```jsx\n\u002F\u002F comparison overhead likely exceeds multiplication cost\nconst n = useMemo(() => x * 2, [x])\n\u002F\u002F vs just: const n = x * 2\n```\n\nBenchmark before memoizing. Use React DevTools Profiler to identify actual\nexpensive renders, then target them specifically.\n",{"id":74,"difficulty":34,"q":75,"a":76},"inline-function-no-memo","Is it always wrong to pass an inline function to a child component?","No. Inline functions are perfectly fine when:\n- The child is **not** wrapped in `React.memo`.\n- The function is not in an effect dependency array.\n- The child re-render is cheap (no deep tree, no expensive computation).\n\n```jsx\n\u002F\u002F fine: Button is not memoized, re-render is cheap\n\u003CButton onClick={() => setOpen(true)} \u002F>\n\n\u002F\u002F needed: DataGrid is memoized and re-renders are expensive\nconst handleSort = useCallback(col => setSort(col), [])\n\u003CDataGrid onSort={handleSort} \u002F>\n```\n\nDefaulting to `useCallback` for every handler is premature optimization that adds\nnoise. Add it when you have a real memoization need.\n",{"id":78,"difficulty":34,"q":79,"a":80},"usememo-vs-state","Should you use useMemo or store the derived value in state?","Always prefer `useMemo` over storing derived data in state. State requires you to\nkeep two values in sync (the source and the derived copy), which can lead to\nbugs. `useMemo` derives the value automatically and stays in sync by definition.\n\n```jsx\n\u002F\u002F anti-pattern: derived state\nconst [items, setItems]   = useState([])\nconst [count, setCount]   = useState(0)\n\u002F\u002F must remember to call setCount every time setItems changes\n\n\u002F\u002F correct: derive in render\nconst [items, setItems] = useState([])\nconst count = useMemo(() => items.length, [items])\n\u002F\u002F or even simpler: const count = items.length (no memo needed here)\n```\n\nFor truly expensive derivations, add `useMemo`; for trivial ones, just compute\nthem inline — no hook needed.\n",{"id":82,"difficulty":34,"q":83,"a":84},"remove-memoization","When should you remove a useMemo or useCallback?","Remove memoization when: (1) profiling shows the memoized path is never hot; (2)\nthe dependency array is so complex or unstable that the memo rarely hits; (3) the\nmemoized value is consumed by a non-memoized child (the stability gains nothing).\n\n```jsx\n\u002F\u002F useless: MutableChild re-renders anyway for other reasons\nconst handler = useCallback(fn, [deps])\n\u003CMutableChild onClick={handler} \u002F>\n\n\u002F\u002F useful: MemoChild skips renders when handler is stable\nconst handler = useCallback(fn, [deps])\n\u003CMemoChild onClick={handler} \u002F>\n```\n\nMemoization is not free — when it doesn't help, it only adds confusion. Keep the\ncode simple; add memos with evidence, remove them without regret.\n",15,null,{"description":11},"React useCallback and useMemo interview questions — referential stability, when to memoize, dependency arrays, performance pitfalls, and React.memo interaction.","react\u002Fhooks\u002Fusecallback-usememo","useCallback & useMemo","Hooks","hooks","2026-06-23","MXYFZ7Z2AY4kVT0nfmeMMGdgogSNiNQOKh6JZxq5veo",[96,100,103,107,111,112,116],{"subtopic":97,"path":98,"order":99},"useState","\u002Freact\u002Fhooks\u002Fusestate",1,{"subtopic":101,"path":102,"order":12},"useEffect","\u002Freact\u002Fhooks\u002Fuseeffect",{"subtopic":104,"path":105,"order":106},"useContext","\u002Freact\u002Fhooks\u002Fusecontext",3,{"subtopic":108,"path":109,"order":110},"useReducer","\u002Freact\u002Fhooks\u002Fusereducer",4,{"subtopic":90,"path":21,"order":20},{"subtopic":113,"path":114,"order":115},"useRef","\u002Freact\u002Fhooks\u002Fuseref",6,{"subtopic":117,"path":118,"order":119},"Custom Hooks","\u002Freact\u002Fhooks\u002Fcustom-hooks",7,{"path":121,"title":122},"\u002Fblog\u002Freact-usecallback-usememo-guide","React useCallback & useMemo — Complete Interview Guide",1782244100848]