هوک useMemo و بررسی تخصصی ()React.useMemo در ری اکت
Published: 2023-11-10 18:10:30


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvz7u9er5fv7u6rn7l1n.png)



زمانیکه نسخه 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 نوشته شده .



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ai8ae9vfbz785lq9dm40.png)


هوک useMemo چیست ؟

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

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

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

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

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

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



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dj6fzrmj3zn8m3rlgbjx.png)


از هوک ()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 )



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tewvv6gypnyhsxk29foy.png)


نحوه استفاده از هوک ()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 در ریکت](https://frontendi.com/react-usememo-hook/)