संक्षिप्त जवाब:
प्रतिक्रिया की गारंटी देता है कि refs को पहले componentDidMount
या componentDidUpdate
हुक से सेट किया जाता है । लेकिन केवल उन बच्चों के लिए जो वास्तव में प्रस्तुत हुए ।
componentDidMount() {
}
componentDidUpdate() {
}
render() {
return <div ref={/* ... */} />;
}
ध्यान दें कि इसका मतलब यह नहीं है कि "प्रतिक्रिया हमेशा इन हुकों को चलाने से पहले सभी रीफ़ सेट करें "।
आइए कुछ उदाहरण देखें जहां रेफरी सेट नहीं होते हैं।
Ref उन तत्वों के लिए सेट नहीं होते हैं, जिनका प्रतिपादन नहीं किया गया था
रिएक्ट केवल उन तत्वों के लिए रेफरी कॉलबैक कहेगा जिन्हें आपने वास्तव में रेंडर से लौटाया था ।
इसका मतलब है कि अगर आपका कोड दिखता है
render() {
if (this.state.isLoading) {
return <h1>Loading</h1>;
}
return <div ref={this._setRef} />;
}
और शुरू this.state.isLoading
में true
, आपको पहले बुलाए जाने की उम्मीद नहीं करनी चाहिए ।this._setRef
componentDidMount
यह समझ में आना चाहिए: यदि आपका पहला रेंडर वापस आया है <h1>Loading</h1>
, तो रिएक्ट के लिए यह जानने का कोई संभव तरीका नहीं है कि किसी अन्य शर्त के तहत यह कुछ और लौटाता है जिसे संलग्न होने के लिए रेफ की आवश्यकता होती है। वहाँ भी है : रेफरी को स्थापित करने के लिए कुछ भी नहीं<div>
तत्व क्योंकि नहीं बनाया गया था render()
विधि ने कहा कि यह रेंडर नहीं किया जाना चाहिए।
तो इस उदाहरण के साथ, केवल componentDidMount
आग लग जाएगी। हालाँकि, जब this.state.loading
परिवर्तन होता हैfalse
, तो आप this._setRef
पहले संलग्न देखेंगे , और फिर componentDidUpdate
फायर करेंगे।
अन्य घटकों के लिए बाहर देखो
ध्यान दें कि यदि आप बच्चों को अन्य घटकों के लिए रेफरी के साथ पास करते हैं तो एक मौका है कि वे कुछ ऐसा कर रहे हैं जो प्रतिपादन को रोकता है (और समस्या का कारण बनता है)।
उदाहरण के लिए, यह:
<MyPanel>
<div ref={this.setRef} />
</MyPanel>
काम नहीं करेगा अगर इसके आउटपुट में MyPanel
शामिल नहीं है props.children
:
function MyPanel(props) {
return <h1>Oops, no refs for you today!</h1>;
}
फिर से, यह बग नहीं है: रीम को सेट करने के लिए रिएक्ट के लिए कुछ भी नहीं होगा क्योंकि DOM तत्व नहीं बनाया गया था ।
यदि वे एक नेस्टेड के लिए पारित कर रहे हैं, तो जीवन चक्र से पहले रेफ को सेट नहीं किया जाता है ReactDOM.render()
पिछले अनुभाग के समान, यदि आप एक बच्चे को रेफरी के साथ किसी अन्य घटक में पास करते हैं, तो संभव है कि यह घटक कुछ ऐसा कर सकता है जो समय में रेफरी को संलग्न करने से रोकता है।
उदाहरण के लिए, शायद यह बच्चे को वापस नहीं कर रहा है render()
, और इसके बजाय ReactDOM.render()
एक जीवन चक्र हुक में बुला रहा है। आप इस का एक उदाहरण पा सकते हैं यहाँ । उस उदाहरण में, हम प्रस्तुत करते हैं:
<MyModal>
<div ref={this.setRef} />
</MyModal>
लेकिन अपने जीवन चक्र विधि में MyModal
एक ReactDOM.render()
कॉल करता है : componentDidUpdate
componentDidUpdate() {
ReactDOM.render(this.props.children, this.targetEl);
}
render() {
return null;
}
रिएक्ट 16 के बाद से, एक जीवनचक्र के दौरान इस तरह के शीर्ष-स्तर के रेंडर कॉल विलंबित होंगे जब तक कि जीवनचक्र पूरे पेड़ के लिए नहीं चलता । यह बताएगा कि आप समय में संलग्न रेफरी क्यों नहीं देख रहे हैं।
इस समस्या का हल नेस्टेड कॉल के बजाय पोर्टल का उपयोग
ReactDOM.render
करना है:
render() {
return ReactDOM.createPortal(this.props.children, this.targetEl);
}
इस तरह हमारे <div>
रेफरी के साथ वास्तव में रेंडर आउटपुट में शामिल है।
इसलिए यदि आप इस समस्या का सामना करते हैं, तो आपको यह सत्यापित करने की आवश्यकता है कि आपके घटक और रेफरी के बीच कुछ भी नहीं है जो बच्चों को प्रदान करने में देरी कर सकता है।
setState
रेफरी को स्टोर करने के लिए उपयोग न करें
सुनिश्चित करें कि आप setState
रिफ कॉलबैक में रेफरी को स्टोर करने के लिए उपयोग नहीं कर रहे हैं , क्योंकि यह एसिंक्रोनस है और "समाप्त" होने से पहले इसे पहले componentDidMount
निष्पादित किया जाएगा।
फिर भी एक मुद्दा?
यदि ऊपर दिए गए सुझावों में से कोई भी मदद नहीं करता है, तो प्रतिक्रिया में एक समस्या दर्ज करें और हम देखेंगे।
this
आपकी कक्षा के बाहर लेक्सिकल स्कोप से वैल्यू कैप्चर करेगा । अपने क्लास के तरीकों के लिए एरो फ़ंक्शन सिंटैक्स से छुटकारा पाने की कोशिश करें और देखें कि क्या यह मदद करता है।