Effects "react" to reactive values (রিয়াক্টিভ ভ্যালুগুলোতে ইফেক্ট রিয়াক্ট করে)
const serverUrl = "https://localhost:1234";
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [roomId]);
// ...
}
উপরের উদাহরণ অনুযায়ী ইফেক্টে দুইটা ভ্যারিয়েবল ব্যাবহার করা হয়েছে, কিন্তু ইফেক্টের ডিপেন্ডেন্সি হিসেবে ব্যাবহার করা হয়েছে একটা ভ্যারিয়েবল roomId
, এটা কেন? কেন serverUrl
ইফেক্টের ডিপেন্ডেন্সিতে ব্যাবহার করা হলোনা ?
এর কারণ হলো serverUrl
হলো একটা স্ট্যাটিক ভ্যালু এবং এটা কম্পোনেন্টের বাহিরে ডিক্লেয়ার করা হয়েছে, তাই এটা কখনই কোন রি-রেন্ডারে চেঞ্জ হবেনা। যেই ভ্যারিয়েবলগুলো কম্পোনেন্টের বাহিরে ডিক্লেয়ার করা হয় এবং যেগুলো কখনো চেঞ্জ হওয়ার সম্ভাবনা নেই,সেগুলো রিয়াক্টিভ ভ্যালু না। আর ইফেক্টের ডিপেন্ডেন্সিতে শুধুমাত্র রিয়াক্টিভ ভ্যালুগুলোই ব্যাবহার করতে হয়।
অন্যদিকে roomId
ভ্যারিয়েবলটা প্রপে এসেছে, প্রপ,স্টেট এগুলা রি-রেন্ডারে চেঞ্জ হতে পারে,তাই এগুলো রিয়াক্টিভ ভ্যালু কেননা এগুলা রিয়াক্টের কম্পোনেন্ট এর ভিতরে ডিক্লেয়ার করা হয়েছে তাই এগুলো রেন্ডারিং এ কেলকুলেট হবে, আর তাই এসব ভ্যালু রিয়াক্টিভ।
যদি serverUrl
ভ্যারিয়েবলটা প্রপ হিসেবে আসতো, তাহলে এটাও রিয়াক্টিভ ভ্যালু হতো। রিয়াক্টিভ ভ্যালু যেগুলো ইফেক্টের মধ্যে ব্যাবহার করা হয়েছে,সেগুলো অবশ্যই ইফেক্টের ডিপেন্ডেন্সিতে এড করা লাগবে।
What an Effect with empty dependencies means (ইফেক্টের ইম্পটি ডিপেন্ডেন্সি মানে কি?)
const serverUrl = "https://localhost:1234";
const roomId = "general";
function ChatRoom() {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, []); // ✅ All dependencies declared
// ...
}
যদি এমন হয় যে আমদের ইফেক্ট শুধুমাত্র একবার রান করবে একবার চ্যাট রুমের সাথে কানেক্ট হবে যখন কম্পোনেন্ট মাউন্ট হবে, পরে আর কখনোই ইফেক্ট রান করার প্রয়োজন নেই, এবং শুধুমাত্র কম্পোনেন্ট আনমাউন্ট হলে কানেকশন স্টপ হবে, তাহলে আমরা ডিপেন্ডেন্সি ভ্যারিয়েবল গুলো কপোনেন্টের বাহিরে নিয়ে স্ট্যাটিক ভ্যালু হিসেবে রাখতে পারি। এবং এতে যেহেতু কোন রিয়াক্টিভ ভ্যালু ইফেক্টের ভিতরে ব্যাবহার করা হয়নি,তাই এখানে ডিপেন্ডেন্সি ইম্পটি থাকতে পারে।
আসলে আমাদের কম্পোনেন্টের মাউন্ট -আনমাউন্ট নিয়ে চিন্তা করার কোন দরকার এ নেই, আমরা শুধুমাত্র এফেক্টের স্টার্ট আর স্টপ লিখবো ইফেক্টের ভিতরে, বাকিটা রিয়াক্ট নিজে বুঝে নিবে। যদি কোন ডিপেন্ডেন্সি দেয়ার প্রয়োজন হয়,সেটা আমদের eslint
সাজেশন দিবে।
All variables declared in the component body are reactive (কম্পোনেন্টের ভিতরে যে সকল ভ্যারিয়েবল ডিক্লেয়ার করা হয়,তা সব রিয়াক্টিভ ভ্যালু)
শুধুমাত্র প্রপ আর স্টেট ই রিয়াক্টিভ ভ্যালু নয়, আমাদের কম্পোনেন্টের ভিতরে ডিক্লেয়ার করা ভ্যারিয়েবলগুলোও রিয়াক্টিভ, কেননা যদি এমন হয় যে আমাদের কম্পোনেন্টের ভিতরে কোন ভ্যালু আমরা কনটেক্সট থেকে রিড করেছি এবং তা কম্পোনেন্টের ভিতরে ডিক্লেয়ার করেছি,সেটাও রিয়াক্টিভ ভ্যালু হতে হবে। আমরা কম্পোনেন্টের ভিতরে শুধু সেই ভ্যারিয়েবল ই রাখবো যেগুলো কম্পোনেন্টের রেন্ডারিং এর সাথে সম্পর্কযুক্ত। এমন কোন ভ্যারিয়েবল যা আমাদের কম্পোনেন্টের রেন্ডারিং সাথে সম্পর্ক নেই, এবং া কখনো পরিবর্তন হউয়ার সম্ভাবনা নেই, সেগুলো আমরা সবসময় কম্পোনেন্ট এর বাইরে ডিক্লেয়ার করবো।
React verifies that you specified every reactive value as a dependency (রিয়াক্ট ভেরিফাই করা যে প্রতিটা রিয়াক্টিভ ভ্যালু ইফেক্টের ডিপেন্ডেন্সিতে এড করা হয়েছে।)
আমরা প্রজেক্ট সেটআপ করার সময় রিয়াক্টের জন্য যেই linter
টা সেটআপ করি,সে সবসময় আমাদের ওয়ার্ন করে যাতে সকল রিয়াক্টিভ ভ্যালু যা ইফেক্টের ভিতরে ব্যাবহার করা হয়েছে সেগুলো যাতে ইফেন্টের ডিপেন্ডেন্সিতে এড করা হয়।
যদি কোন রিয়াক্টিভ ভ্যালু আমরা ইফেক্টের ভিতরে ব্যাবহার করি কিন্তু ডিপেন্ডেন্সিতে এড না করি, তাহলে linter
আমাদের ওয়ার্নিং দিবে, আমরা কখনোই সেই ওয়ার্নিং টাকে সাপ্রেস করবোনা, বরং যেসব ভ্যালু ডিপেন্ডেন্সিতে এড করার জন্য linter
সাজেস্ট করবে সেগুলো আমরা ডিপেন্ডেন্সিতে এড করে নিবো।
আর যদি আমরা চাই যে, আমাদের কম্পোনেন্ট re-Syncronize
না করুক,তাহলে আমরা রিয়াক্টিভ ভ্যালুগুলো কম্পোনেন্ট এর বাহিরে স্ট্যাটিক ভ্যালু হসেবে রাখতে পারি,যেগুলো কখনই চেঞ্জ হবেনা, এবং ইফেক্ট re-Syncronize
হবেনা।