هوک useMemo و بررسی تخصصی ()React.useMemo در ری اکت

·

6 min read

زمانیکه نسخه 16.8 ری اکت منتشر شد یه عالمه هوک باحال بهش اضافه شد مثل هوک useMemo ! در حقیقت هوک useMemo ری اکت به بهینه سازی اپیکیشن ما و بهبود Performance پروژمون کمک میکنه.

امروز میخوایم بصورت تخصصی هوک useMemo ری اکت رو بررسی کنیم و ببینیم که کجاها باید از این هوک استفاده کرد و چه جاهایی نباید ازش استفاده کرد!

اصلا Memoization چی هست و چرا باید ازش استفاده کنیم ؟

زمانیکه وضعیت / state یک کامپوننت تو ری اکت تغییر میکنه ، ری اکت اون کامپوننت و همه فرزندانش ( کامپوننت های فرزند ) رو re-Render میکنه.

گاهی اوغات ممکنه کامپوننت فرزند هیچ تغییری نکرده باشه ولی به این دلیل که کامپوننت پدر تغییر حالتی داشته ، ری اکت کامپوننت پدر و تمامی کامپوننت های فرزند رو re-Render میکنه ( بدون توجه به اینکه کامپوننت های فرزند بدون تغییر بودن )

چنین re-Render های بیهوده ای قطعا هزینه بر هستن و Performance اپیکیشن مارو کاهش میدن .

به عنوان یک Front-End Enginner باید تمام تلاش خودمون رو بکنیم که یک اپیکیشن بهینه، با Performance عالی داشته باشیم .

خود ری اکت برای حل این مشکل memo رو معرفی کرد . اگه با memo آشنایی ندارید حتما قبل از ادامه دادن این مقاله ، ابزار ()memo و بررسی تخصصی React.memo رو مطالعه کنید چون هوک useMemo بر پایه ابزار memo نوشته شده .

هوک useMemo چیست ؟

هوک useMemo در ری اکت نتیجه یک تابع رو برای بار اول محاسبه میکنه و نتیجش رو داخل حافظش ذخیره میکنه.

حالا تو re-Render های بعدی ، اون تابع اجرا نمیشه و هیچگونه محاسبه جدیدی انجام نمیده و همون نتیجه ای که قبلا داخل حافظه ذخیره کرده بودیم رو برمیگردونه ( تا زمانیکیه ورودی های تابع تغییر کنه )

خب این فوق العادس 🙂 چرا ؟

چون برخی تابع ها خیلی سنگین هستن و محاسبات پیچیده ای دارن. به کمک هوک ()useMemo میتونیم یکبار این تابع رو render کنیم و نتیجش رو داخل حافظه بسپریم. تو re-Render های بعدی دیگه این تابع محاسبه نمیشه و از همون نتیجه ای که داخل حافظه داریم استفاده میکنیم .

با Memoization میتونی پروژت رو خیلی خیلی بهینه تر کنی !

تکنیک Memoization به شما کمک میکنه Performance اپیکیشن خودتونو بشدت بهبود بدید.

اما یه نکته خیلی مهم اینجا وجود داره :

استفاده نادرست از ()useMemo ممنوع !ا

کثر React Developer ها چون فکر میکنن Memoization تکنیک خیلی خوبیه برای بهبود Performance پروژه ، از اون همه جا استفاده میکنن ( استفاده بی رویه ). اما استفاده نادرست باعث میشه که Performance پروژتون از حالت عادی هم ضعیف تر بشه. ( چون خود useMemo محاسبات انجام میده )

از هوک ()useMemo فقط برای محاسبات سنگین و پیچیده استفاده کنید !

از هوک useMemo فقط برای تابع هایی که محاسبات سنگین و پیچیده ای دارن استفاده کنید . فراموش نکنید که استفاده از هوک React.useMemo برای توابع ساده نتیجه عکس داره.

در حقیقت خود useMemo داره یکسری محاسبات انجام میده و اگه از useMemo برای جاهایی که نیاز به Memoization نداریم استفاده کنیم ، در حقیقت کلی محاسبه اضافی به پروژمون اضافه کردیم .

بطور مثال تو کامپوننت زیر از useMemo برای یک تابع خیلی ساده استفاده کردیم که اینجا اصلا نیازی به Memoization نداریم !

const App({name, family}) {
  const createFullName = useMemo(() => {
     return name+family
  }, [name, family]) // اینجا مواردی  رو مشخص میکنیم که میخوایم درصورت تغییر مقدار ، تابع مجدد اجرا بشه

  return <ExpensiveComponent fullName={createFullName}/>
}

تو کامپوننت بالا ، تابع createFullName هزینه محاسباتی سنگینی نداره و نباید اینجا از useMemo استفاده میکردیم.

اما اتفاقی که تو کامپوننت بالا میوفته این هست که نتیجه تابع createFullName یکبار محسابه میشه و تو حافظه ذخیره میشه و تا زمانی که name و family تغییری نکنن ، این تابع re-Render و محاسبه مجدد نخواهد شد.

حالا بیاید به حالت ساده این کامپوننت نگاهی بندازیم :

const App({name, family}) {
  const createFullName = ()=> {
     return name+family
  }

  return <ExpensiveComponent fullName={createFullName}/>
}

ما یه تابع رو به 2 صورت داریم . با useMemo و بدون useMemo !

اما واقعا از کدوم باید استفاده کنیم ؟!

پاسخ ساده به این سوال این هست که اگه محاسبه و نتیجه اون تابع ساده هست ، نیازی به useMemo ندارید اما اگه هزینه محاسباتی اون تابع بالاست ، بهتره که از useMemo استفاده کنید .

همچنین همیشه به نتیجه اون تابع هم دقت کنید . اگه نتیجه اون تابع ( مقداری که return میشه ) از مقادیر ساده جاوااسکریپتی هست ( primitive ) پس نیازی به useMemo نیست ( نوع دیتا primitive مثل string , number , boolean , null ,undefind )

نحوه استفاده از هوک ()useMemo

کد زیر ، یک مثال خیلی ساده از نحوه استفاده از هوک ()useMemo در ری اکت هست :

const cachedValue = useMemo(function,dependencies)

خود هوک useMemo ، دو مقدار اصلی از ما دریافت میکنه .

مقدار اول یک تابع / Function هست و در حقیقت همون تابعی هست که هزینه محاسباتی بالایی داره و میخوایم از اجرای مجددش در هربار re-Render جلوگیری کنیم .

مقدار دوم dependencies هست. تو بخش dependencies باید لیست متغیر هایی رو قرار بدیم که میخوایم با تغییر پیدا کردن مقدارشون ، تابع ما مجدد محاسبه بشه . ( با فرمت آرایه )

نتیجه این function در متغیری به نام cashedValue ذخیره میشه که از اون میتونیم در هر کجا از اپیکیشن خودمون استفاده کنیم . نکته این هست که این تابع برای بار اول محاسبه میشه و مقدارش در cashedValue ذخیره میشه و تا زمانیه dependencies ها تغییر پیدا نکنن ، این تابع مجدد محاسبه نمیشه .

اتفاقی که در re-Render های بعدی میوفته این هست که :

ری اکت به dependencies های useMemo نگاه میکنه که ببینه آیا این dependencies ها نسبت به render قبلی فرق کردن یا نه ؟

اگه تفاوتی نداشتن ، از همون مقدار memo شده ( به حافظه سپرده شده ) استفاده میکنه .

اما اگه تفاوت داشتن ، مجدد اون تابع رو محاسبه میکنه.

تفاوت هوک useMemo با memo در ری اکت چیست ؟

هوک ()useMemo و ابزار ()memo هر دو جز قابلیت های معرفی شده توسط React هستن که به بهبود Performance اپیکیشن ما کمک میکنن.

اما با همدیگه تفاوت ها و کاربرد های مختلفی دارن .

ابزار memo

در حقیقت Memo یک HOC ( Higher Order Component ) هست که برای به حافظه سپردن یک کامپوننت مورد استفاده قرار میگیره . زمانیکه از react.memo استفاده میکنیم ، تا زمانیکه props های اون کامپوننت تغییری نکنه ، این کامپوننت re-Render نمیشه .

هوک useMemo

هوک useMemo برای به حافظه سپردن مقدار یک محاسبه ( تابع ) کاربرد داره . زمانیکه از ()useMemo استفاده میکنیم ، مقدار یک تابع رو به حافظه میسپریم و تا زمانیکه dependencies های اون تابع تغییری نکرده باشه ، اون تایع در re-Render های بعدی دیگه محاسبه نمیشه و از همون مقدار کش شده استفاده میشه .

خلاصه بخوایم بگیم ، از ()React.memo برای کش کردن یک Component در React استفاده میشه اما از ()React.useMemo برای کش کردن مقدار یک تابع در React استفاده میشه .

ادامه این مقاله

لطفا برای مطالعه ادامه این مقاله در وبسایت فِرانت اِندی + مثالها و تیکه کد های بیشتر روی لینک زیر کلیک کنید :

useMemo در ری اکت