useMemo() and useCallback() are React performance hooks that help avoid unnecessary work during re-renders by memoizing values and functions.
useMemo() memoizes computed valuesuseCallback() memoizes function referencesBoth useMemo() and useCallback() are React hooks that help improve performance by memoizing values or functions between renders.
- useMemo() caches the result of a computation
- useCallback() caches the function itself
useMemo() prevents expensive calculations from running on every render. It only recomputes when dependencies change.
// useMemo prevents expensive factorial calculation on every render
import React, { useMemo, useState } from "react";
function FactorialCalculator() {
const [num, setNum] = useState(5);
const [count, setCount] = useState(0);
const factorial = useMemo(() => {
console.log("Calculating factorial...");
let result = 1;
for (let i = 1; i <= num; i++) result *= i;
return result;
}, [num]);
return (
<div>
<h4>Factorial of {num}: {factorial}</h4>
<input
type="number"
value={num}
onChange={(e) => setNum(Number(e.target.value))}
/>
<button onClick={() => setCount(count + 1)}>
Re-render ({count})
</button>
</div>
);
}
export default FactorialCalculator;
The factorial function runs only when num changes, not when the button triggers a re-render.
In React, functions are recreated on every render. useCallback() keeps the same function reference unless its dependencies change — crucial for preventing child re-renders.
// useCallback stabilizes function reference passed to child
import React, { useState, useCallback } from "react";
import Child from "./Child";
function Parent() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prev => prev + 1);
}, []);
return (
<div>
<h4>Count: {count}</h4>
<Child onClick={increment} />
</div>
);
}
export default Parent;
// Child.js
import React from "react";
function Child({ onClick }) {
console.log("Child rendered");
return <button onClick={onClick}>Increment</button>;
}
export default React.memo(Child);
Without useCallback(), increment would be recreated each render, causing the memoized child to re-render.
useMemo()useCallback()Always profile before applying memoization — unnecessary caching can waste memory.
Render Flow:
useMemo() checks dependency changesuseCallback() preserves function identityTest how Dependency changes vs. Unrelated updates affect the result.
useCallback() with React.memo()useMemo() for derived data, not constantsuseMemo()useCallback()Goal: Understand how memoization reduces redundant renders and improves performance.