React Hook useEffect has a missing dependency: 'x'. Either include it or remove the dependency array.বেশিরভাগ বিকাশকারী একটি eslint-অক্ষম মন্তব্যের মাধ্যমে এটিকে নীরব করে। এটি কাজ করে যতক্ষণ না এটি একটি বাসি-ডেটা বাগ সৃষ্টি করে যা খুঁজে পেতে এক দিন সময় নেয়। সতর্কতা সাধারণত সঠিক, এবং প্রতিটি পরিস্থিতির জন্য একটি সঠিক সমাধান আছে।
📋 Table of Contents
- কেন সতর্কতা বিদ্যমান
- ঠিক 1: শুধু নির্ভরতা যোগ করুন
- ফিক্স 2: এটি যোগ করার পরে প্রভাব লুপ হয়
- ফিক্স 3: ফাংশন নির্ভরতা — কলব্যাক ব্যবহার করুন
- ফিক্স 4: আপনার রি-রানিং ছাড়াই সর্বশেষ মান প্রয়োজন
- ফিক্স 5: নিজস্ব পূর্ববর্তী মান থেকে অবস্থা আপডেট করা হচ্ছে
- যখন নিয়ম অক্ষম করা আসলে সঠিক
- আপনি এমনকি একটি প্রভাব প্রয়োজন?
- সিদ্ধান্ত নির্দেশিকা
- প্রায়শই জিজ্ঞাসিত প্রশ্ন
- উপসংহার
কেন সতর্কতা বিদ্যমান
নির্ভরতা অ্যারে প্রতিক্রিয়া জানায় কখন একটি প্রভাব পুনরায় চালাতে হবে। যদি প্রভাবটি তালিকাভুক্ত নয় এমন একটি মান পড়ে, তাহলে প্রভাবটি রেন্ডার থেকে মানটিকে ধরে রাখে যেখানে এটি শেষ চালানো হয়েছিল — একটি বাসি বন্ধ। কোড সঠিক দেখায় এবং ভুল আচরণ করে।
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(r => r.json())
.then(setUser);
}, []); // ⚠️ missing dependency: 'userId'
return <div>{user?.name}</div>;
}
একটি খালি অ্যারের সাথে একবার আনা হয়। ব্যবহারকারী 1 থেকে ব্যবহারকারী 2 তে নেভিগেট করুন এবং উপাদানটি চিরকালের জন্য ব্যবহারকারী 1 দেখায়। সতর্কতা ঠিক এই ভবিষ্যদ্বাণী.
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(r => r.json())
.then(setUser);
}, [userId]); // ✅ refetches whenever userId changes
ঠিক 1: শুধু নির্ভরতা যোগ করুন
বেশিরভাগ ক্ষেত্রে সতর্কতাটি সঠিক এবং নির্ভরতা যোগ করা সম্পূর্ণ সমাধান। এটি প্রথমে করুন এবং শুধুমাত্র আরও তদন্ত করুন যদি এটি একটি লুপ সৃষ্টি করে।
ফিক্স 2: এটি যোগ করার পরে প্রভাব লুপ হয়
নির্ভরতা অ্যারেতে একটি বস্তু, অ্যারে বা ফাংশন যোগ করা প্রায়ই একটি অসীম লুপ সৃষ্টি করে, কারণ সেগুলি প্রতিটি রেন্ডারে পুনরায় তৈরি করা হয় এবং রেফারেন্স দ্বারা তুলনা করা হয়।
function Search({ filters }) {
const [results, setResults] = useState([]);
useEffect(() => {
search(filters).then(setResults);
}, [filters]); // new object identity every render -> infinite loop
}
বস্তুর পরিবর্তে আদিম মানের উপর নির্ভর করুন।
useEffect(() => {
search({ query, category }).then(setResults);
}, [query, category]); // strings compare by value — stable
যখন বস্তুটি প্রকৃতপক্ষে পিতামাতার কাছ থেকে আসে, তখন এটিকে সেখানে স্মরণ করুন।
// Parent
const filters = useMemo(
() => ({ query, category }),
[query, category]
);
return <Search filters={filters} />;
ফিক্স 3: ফাংশন নির্ভরতা — কলব্যাক ব্যবহার করুন
কম্পোনেন্ট বডিতে ঘোষিত একটি ফাংশন প্রতিটি রেন্ডারে একটি নতুন মান, তাই এটিকে তালিকাভুক্ত করা প্রভাবটিকে অবিরামভাবে চালায়।
function Dashboard({ userId }) {
// Recreated every render.
const loadData = async () => {
const res = await fetch(`/api/data/${userId}`);
return res.json();
};
useEffect(() => {
loadData().then(setData);
}, [loadData]); // loops
}
দুটি সঠিক সংশোধন. যদি ফাংশনটি শুধুমাত্র প্রভাব দ্বারা ব্যবহৃত হয়, তবে এটিকে ভিতরে নিয়ে যান – সবচেয়ে পরিষ্কার বিকল্প, কারণ নির্ভরতা সম্পূর্ণরূপে অদৃশ্য হয়ে যায়।
useEffect(() => {
async function loadData() {
const res = await fetch(`/api/data/${userId}`);
setData(await res.json());
}
loadData();
}, [userId]); // ✅ only the primitive is a dependency
যদি ফাংশনটি কম্পোনেন্টের অন্যান্য অংশের সাথে ভাগ করা হয় তবে এটিকেuseCallback.
const loadData = useCallback(async () => {
const res = await fetch(`/api/data/${userId}`);
return res.json();
}, [userId]);
useEffect(() => {
loadData().then(setData);
}, [loadData]); // ✅ identity only changes when userId changes
ফিক্স 4: আপনার রি-রানিং ছাড়াই সর্বশেষ মান প্রয়োজন
কখনও কখনও একটি প্রভাব বৈধভাবে একবার চালানো উচিত, কিন্তু ভিতরে কলব্যাক বর্তমান মান প্রয়োজন. একটি রেফ একটি পরিবর্তনযোগ্য মান ধারণ করে যা নির্ভরতাগুলিতে অংশগ্রহণ করে না।
function Chat({ onMessage }) {
const onMessageRef = useRef(onMessage);
// Keep the ref current on every render.
useEffect(() => {
onMessageRef.current = onMessage;
});
useEffect(() => {
const socket = new WebSocket('wss://example.com');
socket.onmessage = (e) => onMessageRef.current(e.data);
return () => socket.close();
}, []); // ✅ connects once, always calls the latest handler
}
সাবস্ক্রিপশন, টাইমার এবং ইভেন্ট শ্রোতাদের জন্য এটি সঠিক প্যাটার্ন যেখানে প্রতিটি প্রপ পরিবর্তনে পুনরায় সংযোগ করা ভুল হবে।
ফিক্স 5: নিজস্ব পূর্ববর্তী মান থেকে অবস্থা আপডেট করা হচ্ছে
পরবর্তী অবস্থা গণনা করার জন্য পড়ার অবস্থা সেই অবস্থাটিকে একটি নির্ভরতা করে তোলে, যা সাধারণত একটি লুপ সৃষ্টি করে। আপডেটার ফর্ম নির্ভরতা সরিয়ে দেয়।
// Loops: count changes -> effect re-runs -> count changes...
useEffect(() => {
const id = setInterval(() => setCount(count + 1), 1000);
return () => clearInterval(id);
}, [count]);
// ✅ No dependency on count at all.
useEffect(() => {
const id = setInterval(() => setCount(c => c + 1), 1000);
return () => clearInterval(id);
}, []);
যখন নিয়ম অক্ষম করা আসলে সঠিক
একটি বৈধ ক্ষেত্রে রয়েছে: একটি সত্যিকারের মাউন্ট-অনলি প্রভাব যেখানে আপনি ইচ্ছাকৃতভাবে প্রাথমিক মান চান এবং অন্য কিছু নয়। প্রথম রেন্ডারে বিশ্লেষণ হল আদর্শ উদাহরণ।
useEffect(() => {
analytics.track('page_view', { page: pageName });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); // Intentional: fire once with the initial pageName.
আপনি যদি নিয়মটি অক্ষম করেন তবে কেন ইচ্ছাকৃতভাবে বাদ দেওয়া হয়েছে তা ব্যাখ্যা করে একটি মন্তব্য লিখুন। একটি খালি নিষ্ক্রিয় মন্তব্য এমন কারো থেকে আলাদা করা যায় না যিনি সতর্কতাটি বুঝতে পারেননি, যার মধ্যে ছয় মাসের মধ্যে নিজের জন্যও রয়েছে৷
আপনি এমনকি একটি প্রভাব প্রয়োজন?
বিস্তৃত-ডিপস সতর্কতার একটি বড় অংশ এমন প্রভাব থেকে আসে যা বিদ্যমান থাকা উচিত নয়। দুটি সাধারণ ক্ষেত্রে:
প্রাপ্ত রাষ্ট্র. প্রপস বা স্টেট থেকে একটি মান গণনা করার জন্য কোনও প্রভাবের প্রয়োজন নেই।
// Unnecessary effect, extra render, and a dependency warning.
const [fullName, setFullName] = useState('');
useEffect(() => { setFullName(`${first} ${last}`); }, [first, last]);
// ✅ Just calculate it during render.
const fullName = `${first} ${last}`;
একটি অনুষ্ঠানে প্রতিক্রিয়া. একটি ইভেন্ট হ্যান্ডলারের অন্তর্গত লজিক প্রায়ই হ্যান্ডলার সেট করে এমন একটি প্রভাব দেখার অবস্থায় শেষ হয়।
// ✅ Do the work where the event happens.
function handleSubmit() {
submitForm(data);
analytics.track('form_submitted');
}
প্রভাবগুলি প্রতিক্রিয়ার বাইরের সিস্টেমগুলির সাথে সিঙ্ক্রোনাইজ করার জন্য – নেটওয়ার্ক, সদস্যতা, DOM, টাইমার। যদি বাহ্যিক কিছু জড়িত না থাকে তবে একটি প্রভাব সম্ভবত ভুল টুল।
সিদ্ধান্ত নির্দেশিকা
| পরিস্থিতি | ঠিক করুন |
|---|---|
| সতর্কতার নাম একটি আদিম | অ্যারেতে এটি যোগ করুন |
| অবজেক্ট বা অ্যারে একটি লুপ সৃষ্টি করে | এর আদিম ক্ষেত্রের উপর নির্ভর করে, বাuseMemo উৎসে |
| ফাংশন একটি লুপ সৃষ্টি করে | এটি প্রভাব ভিতরে সরান, অথবাuseCallback |
| সর্বশেষ মান প্রয়োজন, পুনরায় চালানো উচিত নয় | এটি একটি রেফারেন্সে সংরক্ষণ করুন |
| পূর্ববর্তী অবস্থা থেকে রাজ্যের উৎপত্তি | আপডেটার ফাংশন ফর্ম ব্যবহার করুন |
| মান প্রপস বা অবস্থা থেকে গণনা করা হয় | রেন্ডারের সময় প্রভাব মুছুন এবং গণনা করুন |
| প্রকৃতপক্ষে শুধুমাত্র মাউন্ট | একটি লিখিত যুক্তি দিয়ে নিয়ম নিষ্ক্রিয় করুন |
প্রায়শই জিজ্ঞাসিত প্রশ্ন
প্রশ্নঃ কেন আমার প্রভাব বিকাশে দ্বিগুণ হয়?
উত্তর: কঠোর মোড ইচ্ছাকৃতভাবে সারফেস মিসিং ক্লিনআপ ফাংশনগুলিতে উপাদানগুলিকে মাউন্ট করে, আনমাউন্ট করে এবং পুনরায় মাউন্ট করে। উৎপাদনে তা হয় না। যদি ডাবল-চালনা কিছু ভেঙ্গে যায়, আপনার প্রভাব একটি পরিষ্কার অনুপস্থিত.
প্রশ্ন: আমি কি শুধু এক্সজুস্টিভ-ডেপস নিয়ম বন্ধ করতে পারি?
উত্তর: আপনি করতে পারেন, এবং আপনি বাসি-বন্ধ বাগগুলি পাঠাবেন যেগুলি ট্রেস করা অত্যন্ত কঠিন। নিয়ম বাস্তব ত্রুটি ধরা; এটি চালু রাখুন এবং কারণগুলি ঠিক করুন।
প্রশ্ন: সর্বত্র কলব্যাক ব্যবহার করলে কর্মক্ষমতা ক্ষতিগ্রস্থ হয়?
উত্তর: সামান্য – এটি মেমরি এবং তুলনা কাজের খরচ করে। এটি ব্যবহার করুন যেখানে পরিচয়ের স্থিতিশীলতা আসলে গুরুত্বপূর্ণ, যেমন নির্ভরতা অ্যারে এবং মেমোয়েজ করা শিশুদের, প্রতিটি ফাংশনে প্রতিফলিতভাবে নয়।
প্রশ্নঃ রিঅ্যাক্ট কম্পাইলার সম্পর্কে কি?
উত্তর: এটি অনেক স্মৃতিচারণকে স্বয়ংক্রিয় করে যেuseCallback এবংuseMemo হাত দ্বারা করুন, যা এই সতর্কতাগুলির একটি বিভাগকে সরিয়ে দেয়। আপনার প্রভাব আসলে কোন মানগুলির উপর নির্ভর করে তা বোঝার প্রয়োজনীয়তা দূর করে না।
প্রশ্ন: আমার প্রভাবের একটি মান প্রয়োজন কিন্তু এটি পরিবর্তিত হলে পুনরায় চালানো উচিত নয়। একটি রেফ একটি হ্যাক?
উত্তর: না, এটি সেই পরিস্থিতির জন্য নথিভুক্ত প্যাটার্ন। একটি পৃথক প্রভাবে রেফ আপডেট রাখা এবং পড়া.current দীর্ঘজীবী প্রভাব ভিতরে মূর্তিপূর্ণ.
উপসংহার
সম্পূর্ণ-ডিপস সতর্কতা একটি বাগ ডিটেক্টর, কোন উপদ্রব নয়। প্রথমে নির্ভরতা যোগ করুন; যদি এটি লুপ হয়, তাহলে আদিমদের সাথে পরিচয় সমস্যাটি ঠিক করুন,useMemo, অথবাuseCallback; রি-চালনা ছাড়া আপনার বর্তমান মানগুলির প্রয়োজন হলে একটি রেফ ব্যবহার করুন; স্ব-রেফারেন্সিয়াল লুপগুলি ভাঙতে স্টেট আপডেটার ফর্ম ব্যবহার করুন; এবং প্রভাব সম্পূর্ণরূপে মুছে ফেলুন যখন মান শুধুমাত্র উদ্ভূত হয়। প্রকৃত মাউন্ট-অনলি ইফেক্টের জন্য eslint-অক্ষম রিজার্ভ করুন, এবং কেন বলে সর্বদা একটি মন্তব্য করুন।
🔗 Share this article
✍️ Leave a Comment