দুটো হুকই একই অন্তর্নিহিত কাজ করে — শেষবারের পর ইনপুট না বদলালে কাজ আবার না করা — দুই ভিন্ন ধরনের মানে প্রয়োগ করা: একটি হিসাব করা ফলাফল, আর একটি ফাংশন।
একটি কম্পোনেন্ট ফাংশন প্রতিটি render-এ আবার চলে, মানে এর ভেতরে হিসাব করা যেকোনো কিছু প্রতিবার আবার হিসাব হয় — সত্যিকারভাবে ব্যয়বহুল আর বদলানোর দরকার নেই এমন কাজসহ:
function ProductList({ products, filter }) {
const filtered = products.filter((p) => p.category === filter); // recalculated every render
return <ul>{filtered.map((p) => <li key={p.id}>{p.name}</li>)}</ul>;
}useMemo একটি হিসাব করা মান ক্যাশ করে, শুধু dependency array-তে (useEffect থেকে একই প্যাটার্ন) কিছু আসলে বদলালে তা পুনরায় হিসাব করে:
function ProductList({ products, filter }) {
const filtered = useMemo(
() => products.filter((p) => p.category === filter),
[products, filter]
);
return <ul>{filtered.map((p) => <li key={p.id}>{p.name}</li>)}</ul>;
}ডিফল্টভাবে প্রতিটি render-এও একটি নতুন ফাংশন তৈরি হয় — সাধারণত ক্ষতিকর নয়, কিন্তু এটা গুরুত্বপূর্ণ হয়ে ওঠে যখন সেই ফাংশন একটি memoized child কম্পোনেন্টে (পরের Performance Basics পাঠের React.memo-এর মাধ্যমে) একটি প্রপ হিসেবে পাস করা হয়, কারণ লজিক অভিন্ন হলেও একটি "নতুন" ফাংশন প্রপ একটি পরিবর্তনের মতো দেখায়। useCallback এর dependency না বদলালে render জুড়ে একই ফাংশন রেফারেন্স রাখে:
function Parent({ items }) {
const handleSelect = useCallback((id) => {
console.log('Selected:', id);
}, []); // same function reference every render
return <ExpensiveList items={items} onSelect={handleSelect} />;
}দুটোই নিজেদের আসল overhead যোগ করে — dependency array তুলনা করা, ক্যাশ করা মান সংরক্ষণ করা। বেশিরভাগ কম্পোনেন্টের জন্য, সেই overhead যেকোনো সাশ্রয়ের চেয়ে বেশি, কারণ বেশিরভাগ হিসাব আর ফাংশন তৈরি সস্তা। নির্দিষ্টভাবে তখনই এদের দিকে যান যখন একটি profiler সত্যিই একটি আসল ধীরগতি দেখিয়েছে, বা আপনি জানেন একটি হিসাব সত্যিকারভাবে ব্যয়বহুল (একটি বড় লিস্ট সর্ট বা ফিল্টার করা) — প্রতিটি মান আর ফাংশনে প্রয়োগ করা একটি ডিফল্ট অভ্যাস হিসেবে নয়।
কোনো ডিফল্ট অভ্যাস নয়
"just in case" সবকিছু useMemo/useCallback-এ মুড়িয়ে দেওয়া একটি সাধারণ অতি-সংশোধন — এটা আসল জটিলতা আর নিজের একটি ছোট পারফরম্যান্স খরচ যোগ করে এমন একটি সুবিধার জন্য যা বেশিরভাগ কম্পোনেন্টে আসলে নেই। অপ্টিমাইজ করার আগে মাপুন।