जाल से बचना: React Hooks में Stale Closures को ठीक करना
Stale closures React में डेटा के चुपचाप नुकसान (silent data loss) का कारण बनते हैं।
आप एक बैकग्राउंड टाइमर के साथ एक डैशबोर्ड बनाते हैं। आप हर 5 सेकंड में डेटा को ऑटो-सेव करने के लिए useEffect हुक के अंदर setInterval का उपयोग करते हैं।
बग तब होता है जब इंटरवल (interval) चलता है। यदि उपयोगकर्ता ने पूरा पेज टाइप किया है, तब भी यह एक खाली डॉक्यूमेंट सेव कर देता है। इंटरवल अतीत में ही अटका रहता है। यह आपके state के पुराने वर्ज़न का उपयोग करता है।
समस्या
जब useEffect चलता है, तो यह अपने स्कोप (scope) में मौजूद वेरिएबल्स को कैप्चर कर लेता है।
- यदि आप state को dependency array से बाहर रखते हैं, तो इंटरवल पहले रेंडर (render) वाले state का उपयोग करता है।
- यदि आप state को dependency array में जोड़ते हैं, तो React हर कीस्ट्रोक (keystroke) पर इंटरवल को रीस्टार्ट कर देता है। इससे परफॉरमेंस खराब होती है और आपका टाइमिंग बिगड़ जाता है।
समाधान: Mutable Ref Pattern
आपको टाइमर को डेटा से अलग करना होगा। अपने नवीनतम state का एक निरंतर संदर्भ (constant reference) रखने के लिए useRef हुक का उपयोग करें। यह री-रेंडर (re-renders) से बचाता है और आपके इंटरवल को स्थिर रखता है।
इसे कैसे लागू करें:
- अपने नवीनतम state को रखने के लिए एक ref बनाएँ।
- जब भी आपका state बदले, उस ref को अपडेट करने के लिए
useEffectका उपयोग करें। - अपने इंटरवल को एक खाली dependency array के साथ शुरू करें ताकि यह केवल एक बार चले।
- अपने इंटरवल कॉलबैक (callback) के अंदर ref का उपयोग करें।
यह तरीका सुनिश्चित करता है कि आपके बैकग्राउंड टास्क हमेशा ताज़ा (fresh) डेटा का उपयोग करें। यह आपके UI को तेज़ और आपके डेटा को सुरक्षित रखता है।
स्रोत: https://dev.to/iprajapatiparesh/escaping-the-trap-fixing-stale-closures-in-react-hooks-4gg7