2015-11-02 16 views
9

मैं एक फॉर्म घटक लिखना चाहता हूं जो अपने बच्चों को प्रमाणित करने के लिए एक विधि निर्यात कर सके। दुर्भाग्य से एक फॉर्म अपने बच्चों पर किसी भी तरीके को "देख" नहीं देता है।प्रतिक्रिया बच्चों के घटक पर कॉल विधियां

यहाँ मैं फार्म का एक संभावित बच्चों को कैसे परिभाषित है:

var Input = React.createClass({ 
    validate: function() { 
    ... 
    }, 
}); 

और यहाँ मैं फार्म वर्ग कैसे परिभाषित है:

var Form = React.createClass({ 
    isValid: function() { 
    var valid = true; 
    this.props.children.forEach(function(component) { 
     // --> This iterates over all children that I pass 
     if (typeof component.validate === 'function') { 
     // --> code never reaches this point 
     component.validate(); 
     valid = valid && component.isValid(); 
     } 
    }); 
    return valid; 
    } 
}); 

मैंने देखा है कि मैं एक बच्चे के घटक पर एक विधि कॉल कर सकते हैं रेफरी का उपयोग करके, लेकिन मैं props.children के माध्यम से एक विधि को कॉल नहीं कर सकता।

क्या इस प्रतिक्रिया व्यवहार का कोई कारण है?

मैं इसे कैसे ठीक कर सकता हूं?

उत्तर

13

तकनीकी कारण यह है कि जब आप बच्चे के घटक तक पहुंचने का प्रयास करते हैं, तो वे अभी तक वास्तव में मौजूद नहीं हैं (डीओएम में)। वे अभी तक आरोहित नहीं किया गया है। उन्हें आपके <Form> घटक को एक निर्माता प्रोप या विधि के रूप में वर्ग प्रतिक्रिया के रूप में पास कर दिया गया है। (इसलिए में नाम वर्ग)।

जैसा कि आप इंगित करते हैं, इसे रेफरी का उपयोग करके अवरुद्ध किया जा सकता है, लेकिन मैं इसकी अनुशंसा नहीं करता। कई मामलों में, रेफरी उस चीज के लिए शॉर्टकट होते हैं जो प्रतिक्रिया के लिए नहीं थी, और इसलिए इससे बचा जाना चाहिए।

शायद यह डिज़ाइन द्वारा किया गया है कि प्रतिक्रियाएं माता-पिता के लिए बच्चों के तरीकों तक पहुंचने में मुश्किल/असंभव बनाती हैं। उन्हें नहीं माना जाता है। बच्चे के तरीके बच्चे के लिए निजी होने पर बच्चे के तरीके में होना चाहिए: वे बच्चे के अंदर कुछ करते हैं जिसे सीधे माता-पिता को ऊपर नहीं बताया जाना चाहिए। यदि वह मामला था, तो माता-पिता के अंदर हैंडलिंग करने से पहले किया जाना चाहिए था। क्योंकि माता-पिता के पास कम से कम सभी जानकारी और डेटा है जो बच्चे के पास है।

अब आपके मामले में, मैं कल्पना करता हूं कि प्रत्येक इनपुट (बच्चे) घटक के पास कुछ विशिष्ट सत्यापन विधि है, जो इनपुट मान की जांच करता है, और परिणाम के आधार पर, कुछ त्रुटि संदेश प्रतिक्रिया करता है। चलो गलत क्षेत्रों के चारों ओर एक लाल रूपरेखा कहते हैं।

तरह से प्रतिक्रिया में, यह इस प्रकार प्राप्त किया जा सकता:

  • <Form> घटक राज्य है, जो एक runValidation बूलियन भी शामिल है।
  • जैसे ही runValidation सत्य पर सेट है, setState({ runValidation: true }); के अंदर स्वचालित रूप से सभी बच्चों को फिर से प्रस्तुत करता है।
  • यदि आप सभी बच्चों के लिए runValidation शामिल करते हैं।
  • तो प्रत्येक बच्चे if (this.props.runValidation) { this.validate() }
  • की तरह कुछ के साथ उनके render() समारोह के अंदर जांच कर सकते हैं जो बच्चे में validate() समारोह निष्पादित करेंगे
  • सत्यापित समारोह भी बच्चे के राज्य (उपयोग कर सकते हैं राज्य नहीं बदला गया है जब नए मंच में आते हैं), और सत्यापन संदेश के लिए इसका उपयोग करें (उदाहरण के लिए 'कृपया अपने पासवर्ड में अधिक जटिल प्रतीकों को जोड़ें')

अब यह क्या ठीक नहीं है, यह है कि आप सभी के बाद फॉर्म स्तर पर कुछ जांच करना चाहते हैं बच्चों ने खुद को प्रमाणित किया है: उदाहरण के लिए जब सभी बच्चे ठीक हैं, तो फॉर्म जमा करें।

इसे हल करने के लिए, आप अंतिम चेक के लिए रेफरी शॉर्टकट लागू कर सकते हैं और जमा कर सकते हैं। और प्रत्येक componentDidUpdate() फ़ंक्शन के अंदर अपने <Form> में एक विधि को कार्यान्वित करें, यह जांचने के लिए कि क्या प्रत्येक बच्चा ठीक है (उदाहरण के लिए हरी सीमा है) और यदि सबमिट किया गया है, और फिर जमा करें। लेकिन एक सामान्य नियम के रूप में, मैं दृढ़ता से उपयोग करने के खिलाफ दृढ़ता से अनुशंसा करता हूं।

अंतिम रूप सत्यापन के लिए, एक बेहतर तरीका है:

  • अपने <Form> जो प्रत्येक बच्चे के लिए बूलियन्स रखती अंदर एक गैर राज्य चर जोड़ें। एनबी, बच्चों को एक नया रेंडर चक्र ट्रिगर करने से रोकने के लिए, यह गैर-राज्य होना चाहिए।
  • प्रत्येक बच्चे को एक (कॉलबैक) प्रोप के रूप में validateForm फ़ंक्शन पास करें।
  • प्रत्येक बच्चे में validate() के अंदर, this.props.validateForm(someChildID) पर कॉल करें जो फ़ॉर्म में चर में संबंधित बूलियन अपडेट करता है।
  • फॉर्म में validateForm फ़ंक्शन के अंत में, जांचें कि क्या सभी बूलियन सत्य हैं, और यदि ऐसा है, तो फॉर्म सबमिट करें (या फॉर्म स्थिति या जो कुछ भी बदलें)।

प्रतिक्रिया (सत्यापन के साथ) में सत्यापन बनाने के लिए एक और अधिक लंबा (और अधिक जटिल) समाधान के लिए आप this article देख सकते हैं।

+0

प्रमाणीकरण के लिए एक चर गैर-राज्य परिवर्तनीय क्यों होना चाहिए? –

+2

क्योंकि जब आप प्रत्येक बच्चे को "ठीक" या "ठीक नहीं" वापस रिपोर्ट करते हैं, तो यह फ़ॉर्म पूरी तरह से फिर से प्रस्तुत करना नहीं चाहता है, जो तब होता है जब आप इसे फॉर्म स्थिति में डालते हैं। आप केवल पूर्ण फॉर्म के लिए राज्य चाहते हैं, और केवल सभी राज्य ठीक होने पर राज्य/पुनः प्रस्तुत करें। – wintvelt

0

मैं अगर मैं कुछ याद कर रहा हूँ यकीन नहीं है, लेकिन @wintvelt क्या सुझाव दिया कोशिश कर के बाद मैं, जब भी मैं की विधि प्रस्तुत करना अंदर runValidation विधि प्रतिक्रिया नामक एक समस्या में पड़ गए क्योंकि मेरे मामले runValidation में से राज्य में परिवर्तन इस प्रकार setState को कॉल करना, इस प्रकार रेंडर विधि को ट्रिगर करना जो स्पष्ट रूप से खराब अभ्यास है क्योंकि रेंडर विधि शुद्ध होनी चाहिए, और यदि willReceiveProps में runValidation डाल दिया गया तो इसे पहली बार नहीं कहा जाएगा क्योंकि if स्थिति अभी तक सत्य नहीं है (यह setState का उपयोग कर मूल घटक में स्थिति बदल दी गई है, लेकिन willReceiveProps की पहली कॉल में यह अभी भी झूठी है)।

+0

शायद इस विषय पर एक और प्रश्न खोलने के लिए सबसे अच्छा है। लेकिन एक स्पष्टीकरण के रूप में: मेरे उत्तर में, अभिभावक (प्रपत्र) में एक बूलियन ध्वज ('रनवालिडेशन') का मालिक है, जो यह निर्धारित करता है कि बच्चे की 'मान्य() विधि को चलाना चाहिए या नहीं। बच्चे के अंदर यह विधि बच्चे के प्रतिपादन का हिस्सा है, और बच्चे की स्थिति को बदलने (या करने की आवश्यकता नहीं है)। 'मान्य()' विधि केवल यह निर्धारित करने के लिए है कि कोई प्रदर्शित सत्यापन संदेश अपडेट किया जाना चाहिए या नहीं। – wintvelt

संबंधित मुद्दे