كلاهما يخزن مؤقتًا شيئًا ما عبر renders بحيث لا يُعاد حسابه/إعادة إنشاؤه في كل مرة:
useMemoيخزن مؤقتًا .
useCallback يخزن مؤقتًا هوية الدالة (وهي useMemo(() => fn, deps)).هي موجودة لتجنب (أ) تكرار العمل الباهظ و(ب) كسر المساواة المرجعية التي تعتمد عليها المكونات المُذكّرة.
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) خاصية "جديدة" وسيُعيد التصيير على أي حال، مما يهزم المذاكرة. الشيء نفسه بالنسبة لكائن تم تمريره إلى مكون مذكّر أو مستخدم في مصفوفة تبعيات useEffect.
const x = useMemo(() => a + b, [a, b]); // ❌ pointless — adding is cheaper than memoizing
useMemo/useCallback المبكر في كل مكان يضيف ضوضاء ويمكن أن يكون أبطأ حتى. (مترجم React 19 يمكنه المذاكرة التلقائية، مما يقلل الحاجة.)