ReactNext
React-documentationIntermediate-2

4.6 How to write effects

Welcome to React Next Documentation Bangla

Synchronizing with Effects

যখন আমাদের কোনও এক্সটার্নাল API নিয়ে কাজ করতে হয় অথবা কোনও সাইড ইফেক্ট (যেমন API কল, এলার্ট দেখানো, ডাটাবেস এক্সেস করা) হ্যান্ডেল করতে হয়, তখন আমরা useEffect ব্যবহার করি।

মনে রাখতে হবে যে যেসব একশন অটোমেটিক ট্রিগার হতে হবে, সেগুলি useEffect এর মাধ্যমে হ্যান্ডেল করতে হবে। অন্যদিকে, যেগুলি ইউজারের কোনও একশনের ভিত্তিতে ট্রিগার হবে, সেগুলি event handler এর মাধ্যমে হ্যান্ডেল করতে হবে।

যেমন ধরুন, আমাদের কম্পোনেন্ট লোড হওয়ার সঙ্গে সঙ্গেই স্ক্রিনে সকল প্রডাক্টের লিস্ট দেখাতে হবে, যা API থেকে আসছে। তাই আমাদের এমন কিছু করতে হবে যে, কম্পোনেন্ট লোড হওয়া মাত্রই অটোমেটিকভাবে API কল হবে। এই অটোমেটিক কাজটাই আমরা useEffect দিয়ে করতে পারি।

অন্যদিকে, যদি কোন একটি প্রডাক্টের কার্ডে Show Details নামে একটি বাটন থাকে, যেখানে ক্লিক করলে প্রডাক্টের ডিটেইলস দেখাবে, তাহলে এটা আমরা event handler দিয়ে করবো।

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


How to Write an Effect (কিভাবে ইফেক্ট লিখতে হয়)

ইফেক্ট লিখতে হলে আমাদের তিনটি স্টেপ ফলো করতে হয়:

  1. Declare an Effect. (ইফেক্ট ডিক্লেয়ার করা)
  2. Specify the Effect dependencies. (ইফেক্ট রান হওয়ার ডিপেন্ডেন্সিগুলো বলে দেওয়া)
  3. Add cleanup if needed. (ইফেক্ট ক্লিন-আপ করা যদি প্রয়োজন হয়)

Declare an Effect. (ইফেক্ট ডিক্লেয়ার করা)

ইফেক্ট ডিক্লেয়ার করার জন্য প্রথমে আমাদের কম্পোনেন্টের ভিতর useEffect হুককে ইম্পোর্ট করতে হবে। তারপর useEffect কে কম্পোনেন্টের টপ লেবেলে কল করতে হবে।

import React, { useEffect } from "react";
 
const App = () => {
  useEffect(() => {
    // effect code will go here
  }, []);
 
  return (
    <div>
      <h1>Hello World!</h1>
    </div>
  );
};
 
export default App;

ইফেক্টের কোড শুধুমাত্র কম্পোনেন্ট রি-রেন্ডার হয়ে যাওয়ার পর স্ক্রিনে যখন ভিজিবল হয়, তখন এক্সিকিউট হয়। এই অবস্থায় ইফেক্টের ভিতরে আমরা যা লিখবো তা প্রতিবার কম্পোনেন্ট রি-রেন্ডার হওয়ার সাথে সাথে রান হবে।

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

Specify the Effect dependencies. (ইফেক্ট রান হওয়ার ডিপেন্ডেন্সিগুলো বলে দেওয়া)

রিয়াক্টের ইফেক্টের উপর আমাদের কন্ট্রোল আনার জন্য আমরা ডিপেন্ডেন্সি এড করবো। এটি আমাদের বলে দেয় যে আমাদের কম্পোনেন্ট কখন কখন রান করা উচিত।

ডিপেন্ডেন্সি এড করার জন্য আমাদের ইফেক্টের সেকন্ড প্যারামিটারে কিছু ভ্যালু ([] অথবা অন্যান্য ডিপেন্ডেন্সি) দিতে হয়।

  • যদি আমরা চাই যে প্রতিবার রি-রেন্ডারে ইফেক্ট কল হবে:
useEffect(() => {
  // code will go here
});

এক্ষেত্রে কোনও ডিপেন্ডেন্সি দিতে হয় না।

  • যদি আমরা চাই যে শুধু প্রথম রেন্ডারে ইফেক্ট কল হবে এবং পরবর্তীতে রি-রেন্ডার হলেও আর ইফেক্ট কল হবে না:
useEffect(() => {
  // code will go here
}, []);

এক্ষেত্রে সেকন্ড প্যারামিটারে শুধু একটি [] দিতে হয়।

  • যদি আমরা চাই যে কম্পোনেন্ট লোড হওয়ার সাথে সাথে একবার রান হবে এবং কোন স্পেসিফিক কিছু চেঞ্জ হলে আবার রান হবে:
useEffect(() => {
  // code will go here
}, [a, b]);

এক্ষেত্রে a এবং b ডিপেন্ডেন্সিতে এড করা হয়েছে। আমরা মাল্টিপল ডিপেন্ডেন্সি এড করতে পারি।

রিয়াক্ট প্রতিবার কম্পোনেন্ট রেন্ডার হয়ে যাওয়ার পর চেক করে দেখবে যে সেই ভ্যালুগুলো আগের রেন্ডারে যা ছিল, পরের রেন্ডারে কি তাই আছে নাকি। এটি Object.is() মেথডের মাধ্যমে করা হয়। যদি কোনও একটি ভ্যালু চেঞ্জ হয়, তবে রিয়াক্ট ইফেক্টকে আবার কল করবে।

Add cleanup if needed. (ইফেক্ট ক্লিন-আপ করা যদি প্রয়োজন হয়)

এখন আমরা একটি উদাহরণ দেখি যাতে আমরা বুঝতে পারি যে কখন আমাদের ক্লিন-আপ করা প্রয়োজন।

ধরি, আমাদের একটি চ্যাট অ্যাপ্লিকেশন আছে। যখনই কোনও ইউজার চ্যাট করার জন্য অ্যাপ্লিকেশনটি অন করে, তখন চ্যাট কম্পোনেন্টে ক্লিক করলে ইফেক্টের মাধ্যমে একটি চ্যাট সার্ভারের সাথে কানেকশন ঘটানো হবে।

import { useEffect } from "react";
import { createConnection } from "./chat.js";
 
export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection();
    connection.connect();
    return () => {
      connection.disconnect(); // ক্লিন-আপ
    };
  }, []);
 
  return <h1>Welcome to the chat!</h1>;
}
export function createConnection() {
  // বাস্তবভাবে সার্ভারের সাথে কানেক্ট করার জন্য
  return {
    connect() {
      console.log("✅ Connecting...");
    },
    disconnect() {
      console.log("❌ Disconnected.");
    },
  };
}

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

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

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

useEffect(() => {
  const connection = createConnection();
  connection.connect();
  return () => {
    connection.disconnect(); // ক্লিন-আপ ফাংশন
  };
}, []);

উপসংহার

useEffect হুক রিয়াক্ট কম্পোনেন্টে সাইড ইফেক্ট পরিচালনার জন্য একটি গুরুত্বপূর্ণ টুল। এর মাধ্যমে আমরা সহজে API কল করা, ডাটাবেস এক্সেস করা, বা অন্য যে কোনও এক্সটার্নাল কাজ সম্পন্ন করতে পারি।

এখানে কিছু মূল পয়েন্ট উল্লেখ করা হলো:

  1. অটোমেটিক ট্রিগার: useEffect হুক ব্যবহার করে আমরা কম্পোনেন্ট লোড হওয়ার সঙ্গে সঙ্গে অটোমেটিকভাবে কাজ সম্পন্ন করতে পারি, যা ইউজারের কোনও একশনের অপেক্ষায় থাকে না।

  2. ডিপেন্ডেন্সি ব্যবস্থাপনা: ডিপেন্ডেন্সি এড করে আমরা নিয়ন্ত্রণ করতে পারি কখন ইফেক্টটি পুনরায় কার্যকর হবে, যা আমাদের কম্পোনেন্টের পারফরম্যান্স এবং আচরণকে উন্নত করে।

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

useEffect ব্যবহারে আমরা আমাদের অ্যাপ্লিকেশনের কার্যকারিতা উন্নত করতে পারি এবং ইউজারের অভিজ্ঞতা আরও সমৃদ্ধ করতে সক্ষম হই।

On this page