Oba cachują coś między renderowaniami, aby nie było to przeliczane/przebudowywane za każdym razem:
useMemocachuje .
Oba cachują coś między renderowaniami, aby nie było to przeliczane/przebudowywane za każdym razem:
useMemo cachuje .useCallback cachuje tożsamość funkcji (to jest useMemo(() => fn, deps)).Istnieją po to, aby uniknąć (a) powtarzania kosztownej pracy i (b) złamania równości referencyjnej, na której zależą zmemoizowane dzieci.
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} />;
}
Bez useCallback, handleSelect jest zupełnie nową funkcją za każdym renderowaniem. React.memo(Grid) zobaczyłby "nowy" prop i i tak by się renderował, pokonując memoizację. To samo dotyczy obiektu przekazywanego zmemoizowanemu dziecku lub używanego w tablicy zależności useEffect.
const x = useMemo(() => a + b, [a, b]); // ❌ pointless — adding is cheaper than memoizing
useMemo/useCallback wszędzie dodaje szumu i może być nawet wolniejsze. (Kompilator React 19 może automatycznie memoizować, zmniejszając potrzebę.)