Fetching data with effects
যখন আমরা রিয়াক্টে ইফেক্টের মাধ্যমে কোন ডাটা fetch
করবো তখন অবশ্যই আমাদেরকে ইফেক্টের ক্লিন-আপ ফাংশন ইমপ্লিমেন্ট করতে হবে এবং ডেভেলপমেন্ড মুডে আমরা যখনি ডাটা fetch
করে স্টেট এ সেট করবো তখন যাতে দুইবার সেট না হয় সেজন্য ইফেক্টের ক্লিন-আপে প্রথমবার setState
কে ইগনোর করতে হবে।
const [data, setData] = useState([]);
useEffect(() => {
let ignore = false;
async function startFatching() {
const fetched = await fetch(`apiurl/${id}`);
const json = await fetched.json();
if (!ignore) {
setData(json);
}
}
startFatching();
return () => {
ignore = true;
};
}, [id]);
দেখেন এখানে আমরা ৩ নাম্বার লাইনে একটা ভ্যারিয়েবল রেখেছি ignore
নামে এবং ৯-১১ নাম্বার লাইনে আমরা স্টেট আপডেট করার আগে চেক করেছি যে ignore
এর ভ্যালু true
কিনা, যদি true
না হয়,সেখেত্রে আমরা স্টেট আপডেট করেছি।
এখন চলুন এই প্যাটার্নটা আরেকটু ভালো করে বুঝি,
আমরা জানি ডেভেলপমেন্ট মুডে প্রতিটা কম্পোনেন্ট দুইবার করে রান হয়, মানে হলো mount --> unmount --> remount
.
তাই প্রথমবার যখন আমাদের কম্পোনেন্ট মাউন্ট হয়েছে তখন আমাদের ইফেক্ট রান হয়েছে এবং সেখানে ignore
এর ভ্যালু false
পেয়েছে, এবং তারের পরের লাইনেই আমাদের ডাটা fatching
এর জন্য একটা asynchronous
ফাংশন startFatching()
কল হয়েছে, asynchronous
ফাংশনটার ক্লোজারের মধ্যে ignore
ভ্যারিয়েবল এর ভ্যালু false
নিয়ে Web API
এর মধ্যে তার ডাটা fatching
এর কাজ করছে।
এর পরে আমাদের এফেক্টের আর কোন কাজ নাই, তাই সে দ্বিতীয়বার রান হউয়ার জন্য কম্পোনেন্টকে unmount
করতে যাবে এমন সময় দেখে একটা ক্লিন-আপ ফাংশন লেখা হয়েছে ইফেক্টের মধ্যে, তাই সে ক্লিন-আপ ফাংশনটা রান করবে, এবং ক্লিন-আপের মধ্যে ignore
ভ্যারিয়েবল এর ভ্যালু true
করে দেয়া হয়েছে,
এই সময়ের মধ্যে যখন startFatching()
ফাংশনটা তার কাজ শেষ করে ফিরে আসবে এবং স্টেট-আপডেট করতে যাবে তখন সে দেখবে তার ক্লোজারের মধ্যে থাকা ignore
ভ্যারিয়েবল এর ভ্যালু true
হয়ে গিয়েছে। তখন সে আর কোন কাজ করবেনা।
এরই মধ্যে যখন কম্পোনেন্ট remount
হবে তখন আবার পুরো কম্পোনেন্ট নতুন করে রান হবে, এবং তখন ignore
ভ্যারিয়েবল এর ভ্যালু false
পাবে, আর startFatching()
ফাংশনটা কল হবে, এবারে কিন্তু কম্পোনেট আর unmount
হবেনা, তাই ক্লিন-আপ ফাংশনও কল হবেনা আর ignore
ভ্যারিয়েবল এর ভ্যালুও চেঞ্জ হবেনা। তখন startFatching()
ফাংশনটা তার কাজ শেষ করে যখন ডাটা নিয়ে ফিরত আসবে তখনও সে ignore
ভ্যারিয়েবল এর ভ্যালু false
পাবে, আর তাই স্টেট আপডেট করে দিবে।
এই প্যাটার্নে করলে আমাদের ডেভেলপমেন্ট মুড এবং প্রোডাকশন মুড দুইটাতে সেফ। দুইবার আমাদের স্টেট আপডেট হবেনা।
যদিও ইফেক্টের মাধ্যমে এভাবে ডাটা ফেচ করাটা বেস্ট এপ্রোচ না, আমরা রিয়াক্ট এপ্লিকেশনে ডাটা ফেচিং এর জন্য React Query (opens in a new tab), useSWR (opens in a new tab), rtkQuery (opens in a new tab) ইত্যাদি চাইলে ব্যবাহার করতে পারি। অথবা আমরা যদি কোন ফ্রেমওয়ার্ক ব্যবাহার করি তাহলে সেখানে বিল্ট-ইন ডাটা ফেচিং মেকানিজম পেয়ে যাবো।