Farnaz Khoshgoftar
Farnaz Khoshgoftar
خواندن ۲ دقیقه·۲ سال پیش

useMemo vs useCallback

-useMemo

-اول باید بدونیم useMemo چیه ؟ یه React hook هست که به عنوان آرگمان اول یه function و به عنوان آرگمان دوم یه آرایه از dependency ها میگیره . در طول رندر اولیه، useMemo فانکشن رو فراخوانی می‌کنه و نتیجه حاصل از اجرای function رو برمیگردونه و توی حافظه ذخیره میکنه . اگر در طول render های بعدی، dependency ها تغییر نکنه، useMemo فانکشن رو فراخوانی نمی کنه و فقط مقدار ذخیره شده رو برمی گردونه.

بریم سراغ یه مثال ، وارد این لینک بشید

توی App.js یه input داریم برای نوشتن و یه دکمه که هر وقت روش کلیک کنی counter یکی زیاد میشه و یه ChildComponent داریم که count , incrementCount رو به عنوان props بهش پاس میدیم.

وقتی داخل input چیزی مینویسیم یا وقتی رو دکمه Increment کلیک میکنیم متوجه تاخیر زیادی میشیم

-دلیلش چیه ؟ توی این مثال ما یه فانکشن سنگییییین داریم :))‌‌ به اسم expensiveFunction که ۲ تا کار انجام میده یه for loop توش نوشتیم که یه delay ایجاد کنه و اینکه سه برابر count رو برمیگردونه

و هر وقت app ما rerender میشه expensiveFunction رو invoke میکنه و همین اتفاق app رو کند میکنه.

در واقع expensiveFunction فقط باید زمانی که رو دکمه Increment کلیک میکنیم call بشه نه زمانی که تو input چیزی مینویسیم

راه حل : ما باید مقدار بازگشتی expensiveFunction رو memoize کنیم (با استفاده از useMemo عزیزم)

فقط کافیه توی خط ۱۷ ام myCount رو اینطوری تعریف کنی

const myCount = React.useMemo(() => {return expensiveFunction(count);}, [count]);

-useCallback

از لحاظ سیتکسی شبیه useMemo هست فقط وقتی که dependency ها تغییر می کنه، function رو برمی گردونه و از rerender شدن غیرضروری جلوگیری میکنه .

وارد این لینک بشید

تقریبا مثل مثال بالا توی App.js یه input داریم برای نوشتن و یه دکمه که هر وقت روش کلیک کنی counter یکی زیاد میشه و یه ChildComponent داریم که count , incrementCount رو به عنوان props بهش پاس میدیم.

-خب حالا مشکل چیه؟ مشکل اینه که وقتی شما توی input چیزی تایپ میکنی ChildComponent داره بیخودی rerender میشه (یعنی هر وقت App ما rerender بشه ChildComponent هم rerender میشه) در صورتی که فقط اگر روی دکمه Increment کلیک شد باید rerender بشه

برای جلوگیری از این اتفاق باید از useCallback استفاده کنیم

فقط کافیه کد خط پایین رو جایگزین خط ۹ ام codesandbox کنی

const incrementCount = React.useCallback(() => setCount(count + 1), [count]);


-خلاصه :useMemo وقتی که dependency ها تغییر میکنن تابع رو فراخوانی میکنه و یه مقدار ذخیره شده رو برمی گردونه و useCallback وقتی که dependency ها تغییر می کنن تابع ذخیره شده رو برمی گردونه .


usememo
Frontend developer at Snapp
شاید از این پست‌ها خوشتان بیاید