Reactive Accelerator
React Js
React Escape Hatches
4.8 - Synchronising with Effects: Fatching Data

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) ইত্যাদি চাইলে ব্যবাহার করতে পারি। অথবা আমরা যদি কোন ফ্রেমওয়ার্ক ব্যবাহার করি তাহলে সেখানে বিল্ট-ইন ডাটা ফেচিং মেকানিজম পেয়ে যাবো।