Entrambi memorizzano qualcosa attraverso i render, quindi non viene ricalcolato/ricreato ogni volta:
useMemomemorizza un .
Entrambi memorizzano qualcosa attraverso i render, quindi non viene ricalcolato/ricreato ogni volta:
useMemo memorizza un .useCallback memorizza l'identità della funzione (è useMemo(() => fn, deps)).Esistono per evitare (a) di ripetere lavoro costoso e (b) di infrangere l'uguaglianza referenziale su cui i figli memoizzati si affidano.
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} />;
}
Senza useCallback, handleSelect è una funzione completamente nuova ad ogni render. Un React.memo(Grid) vedrebbe una prop "nuova" e si rirenderizzerebbe comunque, vanificando la memoizzazione. Lo stesso vale per un oggetto passato a un figlio memoizzato o usato in un array di dipendenze di useEffect.
const x = useMemo(() => a + b, [a, b]); // ❌ pointless — adding is cheaper than memoizing
useMemo/useCallback ovunque aggiunge rumore e può persino essere più lento. (Il compiler di React 19 può auto-memoizzare, riducendo la necessità.)