跳到主要内容

useCallback and useMemo

useCallback = memoize functions, useMemo = memoize values


useCallback

"Memoize callback functions"

useCallback returns a memoized callback that only changes when dependencies change.

"useCallback memoizes callback functions, preventing recreation on every render and optimizing child component re-renders."


useCallback Syntax

useCallback(fn, dependencies)

const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);

"useCallback takes a function and dependency array, returning a memoized version that only changes when dependencies change."


Why useCallback?

Prevent unnecessary re-renders

// ❌ Without useCallback - new function every render
function Parent() {
const [count, setCount] = useState(0);
const handleClick = () => console.log("click");
return <Child onClick={handleClick} />; // Child re-renders
}

// ✅ With useCallback - stable reference
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("click");
}, []);
return <Child onClick={handleClick} />; // Child doesn't re-render
}

"useCallback prevents child components from re-rendering when parent re-renders, by providing stable function references."


useMemo

"Memoize expensive calculations"

useMemo returns a memoized value that only recomputes when dependencies change.

"useMemo memoizes expensive calculations, only recomputing when dependencies change."


useMemo Syntax

useMemo(fn, dependencies)

const expensiveValue = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);

"useMemo takes a function and dependency array, returning a memoized value that only recomputes when dependencies change."


When to Use useMemo

Expensive calculations · Reference equality

Use when:

  • Expensive calculations
  • Need reference equality
  • Preventing child re-renders (with objects/arrays)

"Use useMemo for expensive calculations or when you need stable object/array references to prevent re-renders."


useCallback vs useMemo

useCallback = functions, useMemo = values

HookReturnsUse For
useCallbackFunctionCallbacks, event handlers
useMemoValueCalculations, objects, arrays

"useCallback memoizes functions, useMemo memoizes values. Both use dependency arrays to control when they update."


Common Pattern: Memoized Callbacks

Stable callbacks for memoized children

const Child = React.memo(({ onClick, data }) => {
return <button onClick={onClick}>{data}</button>;
});

function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("clicked");
}, []);

const data = useMemo(() => ({ value: count }), [count]);

return <Child onClick={handleClick} data={data} />;
}

"useCallback and useMemo work together with React.memo to prevent unnecessary child re-renders."


9️⃣ When NOT to Use

Don't over-optimize

Don't use for:

  • Simple calculations
  • Primitive values
  • Functions/values that change every render anyway
  • Premature optimization

"Avoid useCallback/useMemo for simple operations, primitive values, or premature optimization - they have overhead."


Best Practices

✅ Use for expensive operations ✅ Use with React.memo ✅ Include all dependencies ✅ Don't overuse ❌ Don't memoize everything ❌ Don't forget dependencies


"useCallback memoizes functions to prevent recreation on every render, useful for stable callback references. useMemo memoizes values from expensive calculations. Both use dependency arrays. They work with React.memo to prevent unnecessary re-renders. Don't overuse - only for expensive operations or when reference equality matters."


🧠 Ultra-Short Cheat Sheet

useCallback (functions)
useMemo (values)
Dependency arrays
Prevent re-renders
Work with React.memo
Expensive operations
Don't overuse