اذهب إلى المحتوى
  • 1

ما الفرق بين useCallback و useMemo في React.js

مروان محمود3

السؤال

Recommended Posts

  • 1

في react عندما تنشئ function وتمررها الى child component , ففى كل مرة تتغير حالة الparent component ويحدث re-render نجد أن الجافاسكريبت تتعامل وقتها مع الcallback function ع أنها دالة جديدة فيحدث re-render للchild component ,هنا حدثت عملية render اضافية بلا فائدة مما يؤثر سلبا على الاداء,إذا ما الحل؟

الحل أن نقم بعملية memoization للدالة الممررة للchild component حتى تتعامل معها الجافاسكريبت كل مرة ع أنها نفس الدالة مالم يحدث لها تغيير وبهذا نكون عالجنا مشكلة الrender الاضافي مما يحسن الأداء

مثال: 

function Parent({ ... }) {
  const [a, setA] = useState(0);
  const onPureChange = useCallback(() => {doSomething();}, []);
  ... 
  return (
    ...
    <Pure onChange={onPureChange} />
  );
}

في هذا المثال عندما تتغير قيمة a يحدث render لل parent component وال Child component

بينما إذا قمنا باستخدام الuseCallback على هذا الوجه في المثال الادنى:

const [a, setA] = useState(0);
const onPureChange = useCallback(() => {doSomething();}

 لا يحدث render لل child component عند تغيير قيمة الa 

اما بالنسبة لل useMemo فإنها تقم ايضا بعملية memoization ولكن ليس للدالة نفسها وانما للناتج , ويستخدم عندما يكون لدينا دالة تقم بعمليات حسابية طويلة وتستهلك موارد وأداء وفى نفس الوقت لا يتغير ناتج الدالة كثيرا, في هذه الحالة يكن الحل الامثل ان نخزن الناتج فى useMemo hook حتى لا يحدث render اضافى عند تمرير الدالة وفى نفس الوقت لا نحتاج لنداء نفس الدالة كل مرة يحتاجها الchild component لأن ببساطة ناتج الدالة مخزن بالفعل

فلو قمنا باستخدام useMemo عوضا عن useCallback فى المثال السابق,فاننا لسنا فقط نخزن الreference الخاص بالدالة انما ايضا نقم بتخزين ناتج الدالة فلا نحتاج لاستدعائها 

تم التعديل في بواسطة شرف الدين2
اخطاء املائية
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

useCallback
تفيدك في حالة كنت تريد المحافظة على مرجعية دالة تريد انشائها داخل الدالة render في المكون (أو داخل دالة المكون في حال لم يكن مكون صف)

// كل مرة ينفذ فيها هذا السطر ينشئ تابع جديد
const myFunction = () => {/*...*/}

return (
	<div>
		{/* سيتلقى المكون التالي في كل مرة تابع جديد ولن يستطيع معرفةاذا كنت تمرر نفس التابع دومًا */}
		<OtherComponent callback={myFunction} />
	</div>
)



// عند أول تنفيذ لهذا السطر فقط سيتم انشاء تابع جديد
// والمرات القادمة سيعيد التابع التابع الأول نفسه
const myFunction = useCallback(() => {/*...*/} ,[])

return (
	<div>
		{/* سيتلقى المكون التالي نفس التابع في كل مرة */}
		<OtherComponent callback={myFunction} />
	</div>
)

useMemo
تفيدك في حال كان لديك عملية حسابية تستهلك وقتا أو موارد تقوم الدالة بتنفيذ العملية فقط عند تغير المتحولات في المصفوفة الممرة لها (أو لا تقوم أبدا بإعادة تنفيذ العملية في حال لم تمرر قيم للمصفوفة)

// كل مرة ينفذ فيها هذا السطر سنعيد تنفيذ نفس التابع لحساب النتيجة
const value = veryExpensiveCalculation();

return (
	<div>{value}</div>
)



// عند أول تنفيذ فقط لهذا السطر سيتم حساب القيمة
// والمرات القادمة سيعيد نفس الناتج بسرعة دوما
const myFunction = useMemo(() => veryExpensiveCalculation(),[])

return (
	<div>{value}</div>
)

يمكن أيضا استخدام useMemo بطريقة تعمل عمل useCallback (فقط لفهم أوسع لكن حاول استخدام useCallback بدلا عن الطريقة التالية)

// عند أول تنفيذ فقط لهذا السطر سيتم انشاء دالة جديدة
// والمرات القادمة سيعيد نفس الدالة السابقة وبنفس المرجع
const myFunction = useMemo(() => { return () => {/*...*/} },[])

return (
	<div>
		{/* سيتلقى المكون التالي نفس التابع في كل مرة */}
		<OtherComponent callback={myFunction} />
	</div>
)

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...