Ambos almacenan en caché algo entre renders para que no se recompute/recree cada vez:
useMemocachea un .
Ambos almacenan en caché algo entre renders para que no se recompute/recree cada vez:
useMemo cachea un .useCallback cachea la identidad de una función (es useMemo(() => fn, deps)).Existen para evitar (a) repetir trabajo costoso y (b) romper la igualdad referencial de la que dependen los hijos memoizados.
function Table({ rows, onSelect }) {
// (a) expensive computation — recompute only when `rows` changes
const sorted = useMemo(() => rows.slice().sort(byName), [rows]);
// (b) stable function identity — so a React.memo child doesn't re-render,
// and effects depending on it don't re-fire
const handleSelect = useCallback(id => onSelect(id), [onSelect]);
return <Grid rows={sorted} onSelect={handleSelect} />;
}
Sin useCallback, handleSelect es una función completamente nueva en cada render. Un React.memo(Grid) vería una prop "nueva" y se re-renderizaría de todos modos, anulando la memoización. Lo mismo ocurre con un objeto pasado a un hijo memoizado o usado en el array de dependencias de un useEffect.
const x = useMemo(() => a + b, [a, b]); // ❌ pointless — adding is cheaper than memoizing
useMemo/useCallback por todas partes de forma prematura añade ruido y puede incluso ser más lento. (El compilador de React 19 puede memoizar automáticamente, reduciendo la necesidad.)