إزاي تخلي تطبيق React بتاعك صاروخ؟ شرح useMemo و useCallback ببساطة
أكيد مريت بالموقف ده: بتبني تطبيق بـ React، وفجأة تلاقي الـ UI تقيل وبيهنج، أو بتشوف الـ Component بيعمل إعادة تصيير (Re-render) كتير جداً من غير سبب واضح. إحساس محبط فعلاً! ده غالباً بيحصل بسبب إن المكونات عندك بتعمل حسابات تقيلة أو بتعرف دوال جديدة في كل مرة الـ State بتتغير فيها. النهاردة هنتكلم عن "المنقذين": useMemo و useCallback، وإزاي تستخدمهم عشان تحسن أداء تطبيقك (Performance Optimization) زي المحترفين.
Table of contents [Show]
يعني إيه Memoization أصلاً؟
كلمة Memoization ببساطة هي "تخزين النتيجة". بدل ما تخلي التطبيق يحسب عملية حسابية معقدة أو ينشئ دالة في كل مرة الـ Component بيلف فيها (Re-render)، إحنا بنقول لـ React: "خزني النتيجة دي عندك، وماتحسبيهاش تاني إلا لو المدخلات (Dependencies) اتغيرت". ده بيوفر وقت ومعالجة كبيرة جداً.
إمتى نستخدم useMemo؟
استخدم useMemo لما يكون عندك "عملية حسابية تقيلة" (Expensive Calculation). مثلاً لو عندك مصفوفة فيها آلاف العناصر وعايز تعملها فلترة أو ترتيب. من غير useMemo، الكود ده هيتنفذ في كل مرة المكون يعمل Render، وده بيخلي التطبيق بطيء.
شوف المثال ده:
const result = useMemo(() => {
return heavyCalculation(data);
}, [data]);
هنا، React مش هتعيد تشغيل heavyCalculation إلا لو الـ data اتغيرت. لو المكون عمل Render لأي سبب تاني، النتيجة هتكون محفوظة (Cached) وجاهزة فوراً.
إمتى نستخدم useCallback؟
دلوقتي نتكلم عن useCallback. الفرق الجوهري إن useMemo بتخزن "القيمة" (Value)، لكن useCallback بتخزن "الدالة نفسها" (Function Instance). في JavaScript، أي دالة بتتعرف جوه المكون هي دالة جديدة تماماً في كل Render. لو بتبعت الدالة دي لـ Child Component بيستخدم React.memo، المكون الفرعي هيفتكر إن الدالة اتغيرت وهيعمل Re-render حتى لو مفيش داعي.
مثال عملي:
const handleClick = useCallback(() => {
console.log("Button clicked!");
}, []); // مصفوفة فاضية يعني الدالة دي مش هتتغير أبداً
كده المكون الفرعي اللي بيستقبل handleClick مش هيعمل Re-render إلا لو فعلاً فيه حاجة جوه المصفوفة اتغيرت.
نصائح ذهبية عشان ماتقعش في الفخ
- ماتستخدمهمش في كل حتة: دي أكبر غلطة. useMemo و useCallback ليهم تكلفة (Overhead) في الذاكرة. لو العملية بسيطة، سيب React تعمل شغلها، هي سريعة بما يكفي.
- الـ Dependencies مهمة جداً: لو نسيت تحط المتغيرات في مصفوفة التبعية، الكود بتاعك هيشتغل على بيانات قديمة (Stale Data) وهتظهر لك bugs غريبة.
- استخدم React DevTools: دايماً تابع الـ Profiler عشان تعرف إيه المكونات اللي بتعمل Re-render كتير، وبعدين قرر هل محتاج تحسنها ولا لأ.
خاتمة من أخ
يا صديقي المبرمج، التحسين (Optimization) هو فن قبل ما يكون علم. ماتحاولش تعمل Premature Optimization (تحسين قبل وقته) عشان ماتعقدش الكود على الفاضي. ابني تطبيقك الأول، ولو لقيت بطء، ساعتها طلع العدة بتاعتك: useMemo و useCallback، وابتدي ظبط الأداء. الممارسة هي اللي هتخليك تحس إمتى الكود محتاج "تثبيت" وإمتى تسيبه طبيعي.