Και οι δύο αποθηκεύουν κάτι σε cache σε όλα τα renders, ώστε να μην υπολογίζεται/ξαναδημιουργείται κάθε φορά:
Και οι δύο αποθηκεύουν κάτι σε cache σε όλα τα renders, ώστε να μην υπολογίζεται/ξαναδημιουργείται κάθε φορά:
useMemo αποθηκεύει σε cache μια υπολογισμένη τιμή.useCallback αποθηκεύει σε cache την ταυτότητα μιας συνάρτησης (είναι useMemo(() => fn, deps)).Υπάρχουν για να αποφύγετε (α) την επανάληψη δαπανηρής εργασίας και (β) την διάσπαση της referential equality που χρησιμοποιούν οι memoized children.
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} />;
}
Χωρίς useCallback, το handleSelect είναι μια εντελώς νέα συνάρτηση σε κάθε render. Ένα React.memo(Grid) θα δει μια "νέα" prop και θα κάνει re-render ούτως ή άλλως, ακυρώνοντας τη memoization. Το ίδιο για ένα αντικείμενο που μεταβιβάζεται σε ένα memoized child ή χρησιμοποιείται σε ένα useEffect dependency array.
const x = useMemo(() => a + b, [a, b]); // ❌ pointless — adding is cheaper than memoizing
useMemo/useCallback παντού προσθέτει θόρυβο και μπορεί ακόμα να είναι πιο αργή. (Το compiler του React 19 μπορεί να κάνει auto-memoize, μειώνοντας την ανάγκη.)