Mindkettő egy-egy dolgot gyorsítótáraz a renderelések között, így nem kell minden alkalommal újraszámítani/újralétrehozni:
Mindkettő egy-egy dolgot gyorsítótáraz a renderelések között, így nem kell minden alkalommal újraszámítani/újralétrehozni:
useMemo egy számított értéket gyorsítótáraz.useCallback egy függvény identitását gyorsítótáraz (lényegében useMemo(() => fn, deps)).Ezek azért vannak, hogy elkerüljük (a) az ismétlődő drága munkákat és (b) a referenciális egyenlőségek megtörését, amelyekre a memoizált gyermek komponensek támaszkodnak.
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 nélkül a handleSelect minden rendereléskor egy teljesen új függvény. A React.memo(Grid) egy "új" propsot látna és úgyis újrarenderelne, így a memoizálás elveszne. Hasonló a helyzet, ha egy objektumot adunk át egy memoizált gyermeknek, vagy egy useEffect függőségi tömbben használunk.
const x = useMemo(() => a + b, [a, b]); // ❌ pointless — adding is cheaper than memoizing
useMemo/useCallback mindenhol csak zajt ad és még lassabb is lehet. (A React 19 fordítója automatikus memoizálást tud végezni, így csökkentve az igényt.)