هوک useMemo و بررسی تخصصی ()React.useMemo در ری اکت
زمانیکه نسخه 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 فقط برای محاسبات سنگین و پیچیده استفاده کنید !
از هوک useMemo فقط برای تابع هایی که محاسبات سنگین و پیچیده ای دارن استفاده کنید . فراموش نکنید که استفاده از هوک React.useMemo برای توابع ساده نتیجه عکس داره.
در حقیقت خود useMemo داره یکسری محاسبات انجام میده و اگه از useMemo برای جاهایی که نیاز به Memoization نداریم استفاده کنیم ، در حقیقت کلی محاسبه اضافی به پروژمون اضافه کردیم .
بطور مثال تو کامپوننت زیر از useMemo برای یک تابع خیلی ساده استفاده کردیم که اینجا اصلا نیازی به Memoization نداریم !
const App({name, family}) {
const createFullName = useMemo(() => {
return name+family
}, [name, family]) // اینجا مواردی رو مشخص میکنیم که میخوایم درصورت تغییر مقدار ، تابع مجدد اجرا بشه
return
}
تو کامپوننت بالا ، تابع createFullName هزینه محاسباتی سنگینی نداره و نباید اینجا از useMemo استفاده میکردیم.
اما اتفاقی که تو کامپوننت بالا میوفته این هست که نتیجه تابع createFullName یکبار محسابه میشه و تو حافظه ذخیره میشه و تا زمانی که name و family تغییری نکنن ، این تابع re-Render و محاسبه مجدد نخواهد شد.
حالا بیاید به حالت ساده این کامپوننت نگاهی بندازیم :
const App({name, family}) {
const createFullName = ()=> {
return name+family
}
return
}
ما یه تابع رو به 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 استفاده میشه .
بطور خلاصه هوک React.useMemo یکی از ویژگی های ری اکت برای بهینه سازی و بهبود Performance پروژه های ری اکتی هست . هوک useMemo نتیجه یک تابع رو به حافظش میسپاره و تا زمانی که ورودی های اون تابع تغییری نکنن ، تو re-Render های بعدی این تابع رو مجدد محاسبه نمیکنه و از همون نتیجه کش شده استفاده میکنه .
بطور خلاصه از ابزار memo برای کش کردن یک کامپوننت استفاده میکنیم ولی از هوک useMemo برای کش کردن مقدار یک تابع استفاده میکنیم.
درباره احمد احمدنژاد
من یه برنامه نویس و توسعه دهنده وب هستم که عاشق دنیای صفر و یکم❤️
نوشتههای بیشتر از احمد احمدنژاد2 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
سلام وقت بخیر
یک سوالی داشتم در مورد هوک useMemo در ری اکت
هوک useMemo در ری اکت نتیجه یک تابع رو کش میکنه یا خود تابع رو ؟
سلام و درود
این هوک نتیجه یک تابع رو کش میکنه و درصورتی که در دفعات بعد این تابع رو با همون پارامتر های ورودی قبلی صدا بزنید، نتیجه کش شده به شما تحویل داده میشه و تابع مجدد محاسبه نمیشه.