ReactNext
React-documentationIntermediate-2

4.7 Handling effects

Welcome to React Next Documentation Bangla

How to Handle the Effect Firing Twice in Development?

রিয়াক্টে, যখন আমরা একটি কম্পোনেন্ট তৈরি করি, তখন এটি ডেভেলপমেন্ট মোডে ইচ্ছাকৃতভাবে দুইবার রান করে। এর পেছনে মূল কারণ হলো ডেভেলপারদের বাগ খুঁজে বের করতে সহায়তা করা। আমরা যখন দেখি যে আমাদের কম্পোনেন্ট দুইবার রান হচ্ছে, তখন আমাদের উচিত ভাবা যে, কিভাবে আমরা আমাদের ইফেক্টগুলোকে এমনভাবে সাজাতে পারি যাতে কম্পোনেন্টটি দুইবার মাউন্ট হলেও সঠিকভাবে কাজ করে?

ইফেক্ট এবং ক্লিন-আপ ফাংশন

রিয়াক্টে ইফেক্ট ফাংশন ব্যবহার করে আমরা বিভিন্ন কার্যকলাপ (যেমন API কল, সাবস্ক্রিপশন ইত্যাদি) সম্পন্ন করি। কিন্তু সমস্যা হলো, যখন এই ইফেক্টগুলো দুইবার রান করে, তখন আমরা নিশ্চিত হতে চাই যে পূর্ববর্তী ইফেক্টের প্রভাবগুলি সঠিকভাবে মুছে ফেলা হয়েছে। এখানে ক্লিন-আপ ফাংশন একটি গুরুত্বপূর্ণ ভূমিকা পালন করে।

ক্লিন-আপ ফাংশন হলো একটি ফাংশন যা useEffect থেকে রিটার্ন করা হয়। যখন কম্পোনেন্টটি আনমাউন্ট হয় অথবা নির্ভরতাগুলি পরিবর্তিত হয়, তখন এই ফাংশনটি কার্যকর হয়। এটি নিশ্চিত করে যে পূর্ববর্তী ইফেক্টের প্রভাবগুলো পরিষ্কার করা হচ্ছে।

কেন refs ব্যবহার করবেন না?

অনেক ডেভেলপার ref ব্যবহার করে ইফেক্টগুলোকে দুইবার রান হওয়া থেকে আটকানোর চেষ্টা করেন, কিন্তু এভাবে সমস্যা সমাধান হয় না। নিচে একটি উদাহরণ দেওয়া হলো:

const connectionRef = useRef(null);
useEffect(() => {
  // ❌ This won't fix the bug!!!
  if (!connectionRef.current) {
    connectionRef.current = createConnection();
    connectionRef.current.connect();
  }
}, []);

এখানে, হয়তো আপনি ডেভেলপমেন্ট মোডে দেখতে পারেন যে কানেকশন একবার তৈরি হচ্ছে, কিন্তু এতে আসলে সমস্যা ফিক্স হচ্ছে না। যখন ইউজার অন্য পেজে চলে যাবে এবং ফিরে আসবে, তখন আবার নতুন কানেকশন তৈরি হবে, কিন্তু পূর্বের কানেকশন বন্ধ হবে না। এর ফলে মেমরি লিক হতে পারে।

কিছু সাধারণ প্যাটার্ন

এখন চলুন দেখি কখন এবং কেন ক্লিন-আপ ফাংশন প্রয়োজন।

১. Non-React Widgets নিয়ন্ত্রণ করা

যখন আমরা রিয়াক্টের বাইরে UI উপাদান নিয়ন্ত্রণ করি, যেমন ম্যাপের জুম লেভেল, তখন ক্লিন-আপ ফাংশনের প্রয়োজন নাও হতে পারে। উদাহরণ:

useEffect(() => {
  const map = mapRef.current;
  map.setZoomLevel(zoomLevel);
}, [zoomLevel]);

এখানে, zoomLevel পরিবর্তিত হলে শুধুমাত্র নতুন মান সেট হচ্ছে এবং পূর্ববর্তী মানের কোনো প্রভাব পড়ছে না।

২. কিছু API-তে ইরর

কিছু API আছে যা একসাথে দুইবার রান হলে ইরর দিতে পারে। উদাহরণস্বরূপ, HTML এর dialog ট্যাগের showModal মেথড। যদি এটি দুইবার কল হয়, তবে এটি ইরর দিতে পারে। তাই এখানে ক্লিন-আপ প্রয়োজন:

useEffect(() => {
  const dialog = dialogRef.current;
  dialog.showModal();
  return () => dialog.close();
}, []);

এখানে, আমরা নিশ্চিত হচ্ছি যে showModal এর পরে close মেথডটি কার্যকর হবে, অন্যথায় এটি ইরর দেবে।

৩. ইভেন্টে সাবস্ক্রাইব করা

যখন ইফেক্টের ভিতরে ইভেন্ট লিসেনার যুক্ত করি, তখন অবশ্যই ক্লিন-আপ দরকার। ইভেন্ট লিসেনার যুক্ত করা হলে এবং পরে কম্পোনেন্ট আনমাউন্ট হলে ইভেন্ট লিসেনারটি সরাতে হবে।

useEffect(() => {
  function handleScroll(e) {
    console.log(window.scrollX, window.scrollY);
  }
  window.addEventListener("scroll", handleScroll);
  return () => window.removeEventListener("scroll", handleScroll);
}, []);

এখানে, যখন কম্পোনেন্টটি আনমাউন্ট হবে, তখন removeEventListener ফাংশনটি কল হবে, যা মেমরি লিক প্রতিরোধ করে।

৪. এনিমেশন চালানো

যখন আমরা একটি কম্পোনেন্টের ভিতরে এনিমেশন তৈরি করি, তখন ক্লিন-আপ ফাংশন ব্যবহার করা দরকার। এটি নিশ্চিত করে যে কম্পোনেন্ট আনমাউন্ট হলে এনিমেশন রিসেট হবে।

useEffect(() => {
  const node = ref.current;
  node.style.opacity = 1; // এনিমেশন শুরু
  return () => {
    node.style.opacity = 0; // প্রাথমিক মানে রিসেট
  };
}, []);

এখানে, এনিমেশন শেষ হওয়ার পরে আবার opacity রিসেট হয়ে যাচ্ছে, যা ইউজারের অভিজ্ঞতা উন্নত করে।

উপসংহার

রিয়াক্টে ইফেক্ট ব্যবহারের সময় আমাদের অবশ্যই নিশ্চিত হতে হবে যে আমরা সঠিকভাবে ক্লিন-আপ ফাংশন ব্যবহার করছি। এতে করে আমাদের কম্পোনেন্ট যেকোনো পরিস্থিতিতে সঠিকভাবে কাজ করবে এবং বাগের সম্ভাবনা কমবে। এটি আমাদের ডেভেলপমেন্ট প্রক্রিয়াকে সহজতর এবং দক্ষ করে তোলে।

যখনই আমরা কোড লিখি, আমাদের লক্ষ্য হতে হবে কোডটিকে পরিষ্কার, কার্যকর এবং ভবিষ্যতের জন্য স্থিতিশীল রাখা। ক্লিন-আপ ফাংশন ব্যবহারের মাধ্যমে আমরা এই লক্ষ্য অর্জনে একটি গুরুত্বপূর্ণ পদক্ষেপ নিতে পারি।

On this page