2014-10-29 11 views
28

मैं एक सबसे अच्छा अभ्यास रहा हूँ उन एक दिया इकाई को संपादित करने के लिए फार्म के लिए एक ReactJS घटक जिम्मेदार है। यहां बहुत सरल उदाहरण है। वास्तविक रूपों में कई मामलों में कई और फ़ील्ड और अधिक जीयूआई कार्यक्षमता होगी।ReactJS प्रपत्र घटकों के लिए सर्वश्रेष्ठ अभ्यास

React.createClass({ 
    getInitialState: function() { 
     return { 
      entity: { 
       property1: null, 
       property2: null 
      } 
     }; 
    }, 

    handleChange: function(e) { 
     var entity = this.state.entity; 

     switch(e.target.name) { 
      case 'property1': 
       entity.property1 = e.target.value; 
       break; 
      case 'property2': 
       entity.property2 = e.target.value; 
       break; 
     } 

     this.setState({ 
      entity: entity 
     }); 
    }, 

    render: function() { 
     return (
      <div className="entity-form"> 
       <form onChange={this.handleChange}> 
        <input type="text" name="property1" value={this.state.entity.property1} /> 
        <br /> 

        <textarea name="property2" value={this.state.entity.property2}></textarea> 
        <br /> 
       </form> 
      </div> 
     ); 
    } 
}); 

प्रपत्र के क्षेत्र सीधे एक इकाई वस्तु, कि तब एक RESTful API को बचाया जा सकता है संपादित कर रहा है। मैं घटक को अद्यतन करना चाहता हूं क्योंकि उपयोगकर्ता फ़ील्ड बदलता है, इसलिए जीयूआई टाइपिंग के दौरान इनपुट के आधार पर प्रतिक्रिया दे सकता है (जैसे सत्यापन, जानकारी इत्यादि)।

सिद्धांत रूप में, मैं पूरे राज्य वस्तु इकाई है कि संपादित किया जा रहा का प्रतिनिधित्व हो सकता था, इसलिए इकाई के हर संपत्ति प्रथम स्तर राज्य चर है। हालांकि, मैं जीयूआई कार्यों और अन्य क्या घटक करने जा रहा है से संबंधित बातों के लिए अतिरिक्त राज्य चर जोड़ने के लिए सक्षम होना चाहते हैं, तो मैं इकाई वस्तु पसंद करेंगे "इकाई" राज्य के ऊपर चर की तरह एक राज्य चर किया जाना है। वस्तु निश्चित रूप से कुछ और अधिक जटिल वस्तु, एक रीढ़ मॉडल या इसी तरह की तरह हो सकता है, लेकिन इस सरल उदाहरण में, मैं बस एक साधारण वस्तु आवश्यक गुण कण का उपयोग करें।

तो, सबसे अच्छा अभ्यास तरीका की तलाश में बनाने के लिए इस उद्देश्य के लिए घटकों प्रतिक्रिया है, मैं कुछ सवाल हैं:

  1. प्रॉप्स या राज्य।

इस मामले में, मैंने इकाई वस्तु को प्रपत्र के बजाय सामग्री चर के रूप में सामग्री के साथ सामग्री के साथ रखना चुना है। यह माता-पिता को कॉल किए बिना प्रोप इनपुट के दौरान ऑब्जेक्ट को अपडेट करने में सक्षम होना चाहिए और प्रोप को अपडेट करना है। जहां तक ​​मेरा रिएक्ट अनुभव जाता है, यह इस तरह के एक फॉर्म घटक के लिए सबसे अच्छा अभ्यास होगा।

  1. नियंत्रित या अनियंत्रित आदानों।

सरल उदाहरण में ऊपर, मैं नियंत्रित आदानों का उपयोग करें। इससे राज्य को अद्यतन करने और प्रत्येक परिवर्तन पर घटक को फिर से प्रस्तुत करने की ओर जाता है (जैसे टेक्स्ट फ़ील्ड में दर्ज प्रत्येक वर्ण)। क्या यह सबसे अच्छा अभ्यास है? अच्छी बात यह है कि घटक का डिफ़ॉल्ट नियंत्रण होता है, डिफ़ॉल्ट वैल्यू पैरामीटर होने की बजाय, और कुछ घटनाओं (जैसे उपयोगकर्ता सहेजने वाला बटन दबाकर), घटक मान निकालें, इकाई को अपडेट करें और उसे सर्वर पर सहेजें। क्या इस तरह के मामलों में नियंत्रित या अनियंत्रित इनपुट का उपयोग करने के लिए कोई कारण (या राय) है?

    फार्म या हर इनपुट

उदाहरण प्रपत्र टैग पर कोई onChange है के लिए

  • onChange, और इसके किसी भी हर बार कहे जाने के handleChange विधि का कारण बनता है फॉर्म में फ़ील्ड बदल गए हैं। हालांकि, चूंकि इनपुट नियंत्रित होते हैं (मान पैरामीटर हैं), प्रतिक्रिया शिकायत करती है कि इनपुट फ़ील्ड में ऑन चेंज प्रॉपर्टी नहीं है। क्या इसका मतलब यह है कि फॉर्म टैग पर चेंज पर एक सामान्य व्यवहार खराब व्यवहार है, और मुझे इसे हटा देना चाहिए और इसके बजाय प्रत्येक फ़ील्ड पर चेंज रखना चाहिए?

    1. अपडेट कर रहा है अलग-अलग प्रॉपर्टी

    ऊपर के उदाहरण में, मैं क्या इनपुट क्षेत्र अद्यतन (जब handleChange कहा जाता है) किया जा रहा है के आधार पर एक स्विच का उपयोग करें। मुझे लगता है कि मैं इसके बजाय यह सुनिश्चित कर सकता हूं कि सभी फ़ील्ड नाम इकाई के संपत्ति नामों के साथ समन्वयित हो जाएं, और मैं ईवेंट ऑब्जेक्ट (e.target.name) से फ़ील्ड के नाम के आधार पर हैंडल चेंज में इकाई ऑब्जेक्ट के गुण सेट कर सकता हूं।हालांकि, इससे प्रति फ़ील्ड की व्यक्तिगत ज़रूरतें मुश्किल होती हैं, भले ही अधिकांश फ़ील्ड सीधे इकाई इकाई को अपडेट करें। मुझे लगता है कि एक alternativ इनपुट के नाम के आधार पर एक डिफ़ॉल्ट ब्लॉक सेटिंग के साथ एक स्विच है, और किसी भी फ़ील्ड के लिए केस ब्लॉक जिन्हें अद्यतन करने के अन्य तरीकों की आवश्यकता होती है (जैसे इकाई पर इसे सेट करने से पहले मूल्य फ़िल्टर करना)। यदि आप इस तरह से क्षेत्र अद्यतनों को संभालने का कुछ बेहतर तरीका जानते हैं, तो कृपया टिप्पणी करें।

    1. राज्य इकाई इस उदाहरण के

    एक बड़ी समस्या अपडेट कर रहा है, जिस तरह से इकाई वस्तु अद्यतन किया जाता है है। चूंकि हैंडल परिवर्तक में इकाई चर वर्तमान स्थिति से इकाई ऑब्जेक्ट पर सेट है, यह केवल एक सूचक है, और इकाई चर अद्यतन करने से वस्तु को स्थिति में बदल दिया जाएगा। प्रतिक्रिया पृष्ठ कहते हैं कि आपको कभी भी राज्य को अद्यतन नहीं करना चाहिए। कारणों में से एक ऐसा है जिसे मैंने सेटस्टेट को कॉल करने से पहले राज्य को अद्यतन करते समय अनुभव किया है। यदि कोई क्वोनपोनेंट अपडेट विधि हो, तो प्रीस्टेट में नया राज्य होता है, क्योंकि prevState तर्क की सामग्री को componentUpdate को भेजा गया है, जो सेटस्टेट कहलाता था जब राज्य में था। जहां तक ​​मुझे पता है, जावास्क्रिप्ट में किसी ऑब्जेक्ट को क्लोन करने का कोई आसान तरीका नहीं है। तो सवाल यह है कि, जब मैं एक ही राज्य चर के सेटस्टेट को चलाने के बजाय पूरी ऑब्जेक्ट्स को (और ऑब्जेक्ट में अन्य मानों को छूना नहीं) के गुणों को अद्यतन करने की आवश्यकता होती है, तो इस प्रकार के तरीके के बिना ऐसा करने का सबसे अच्छा तरीका क्या है राज्य मिश्रण के?

  • +0

    के लिए _ "सर्वोत्तम प्रथाओं" पूछ _ एक बड़ा लाल झंडा है। ये प्रश्न आमतौर पर राय आधारित होते हैं। यह एक अपवाद नहीं है। – Cerbrus

    +4

    खैर, मैबी सर्वश्रेष्ठ प्रथाओं का सबसे अच्छा शीर्षक नहीं था, हालांकि यदि आप वास्तव में पोस्ट पढ़ते हैं, तो मुझे लगता है कि आप यह मान लेंगे कि प्रश्न बहुत ठोस हैं, और ज्यादातर इस उपयोग के मामले के लिए विशेष मुद्दों को हल करने के सुझावों के बारे में पूछते हैं। SO पर अधिकांश जावास्क्रिप्ट प्रश्नों से अलग नहीं है। – henit

    +2

    नियंत्रित बनाम अनियंत्रित इनपुट का सबसे अच्छा स्पष्टीकरण मैंने अब तक देखा है: http://buildwithreact.com/article/form-elements – Victor

    उत्तर

    5
    1. जो कुछ भी बदलने जा रहा है वह राज्य में जाता है।
    2. यदि आप किसी मौजूदा इकाई को लोड करना और इसे संपादित करना चाहते हैं, तो आप नियंत्रित इनपुट चाहते हैं, और आप तदनुसार मान सेट करना चाहते हैं। मैं डिफ़ॉल्ट से दूर रहना चाहता हूं अधिकांश मामलों में (ड्रॉपडाउन के बाहर)
    3. यह आपके पिछले प्रश्न में वापस आ जाता है। यदि आप कोई मान निर्दिष्ट करते हैं, तो आप एक नियंत्रित इनपुट का उपयोग कर रहे हैं, और आपको किसी भी नियंत्रित इनपुट के लिए ऑन चेंज हैंडलर प्रदान करना होगा, अन्यथा यह पत्थर में सेट है। नियंत्रित इनपुट का लाभ यह है कि उपयोगकर्ता उन्हें संपादित नहीं कर सकते हैं, इसलिए यदि आपके पास कुछ गुण लॉक हो गए थे (शायद केवल पढ़ने के लिए, सुरक्षा कारणों), जब उपयोगकर्ता सहेजने का प्रयास करता है, भले ही वे सीधे HTML संपादित करते हैं, प्रतिक्रिया को खींचना चाहिए वीडीओएम प्रतिनिधित्व से संपत्ति का मूल्य (यहां गलत हो सकता है, लेकिन मेरा मानना ​​है कि मैंने पहले इसका परीक्षण किया है)। वैसे भी, आपको सीधे नियंत्रित इनपुट पर चेंज सेट करना होगा। जहां तक ​​घटना विघटन (फॉर्म स्तर पर) का उपयोग करना है, यह कई घटनाओं के लिए बिल्कुल एक बुरा अभ्यास नहीं है, यह केवल एक विशिष्ट परिदृश्य (नियंत्रित इनपुट) है जहां आपको प्रत्येक तत्व के लिए निर्दिष्ट घटनाओं की आवश्यकता होती है।
    4. पूरी तरह से यह सुनिश्चित नहीं है कि इस पर क्या पूछना है, लेकिन मैंने target.name के बजाय रेफरी का उपयोग किया।
    5. तो, आप सही हैं कि आपको सीधे राज्य को कभी नहीं बदलना चाहिए, और यह दस्तावेज़ों से एक मुश्किल बिट है। प्रतिक्रिया सीधे राज्य को बदलने जा रही है, यह सिर्फ सेटस्टेट के माध्यम से कार्यान्वयन में करने जा रही है। यदि आप इस विधि कॉल के बाहर राज्य को बदलते हैं, तो अप्रत्याशित चीजें घटित होंगी और त्रुटियां फेंक दी जाएंगी।

    mustComponentUpdate केवल उथले तुलना करता है, लेकिन यहां कुछ समाधान हैं।

    एक वस्तु को स्ट्रिंग करना है, यह एक त्वरित और गंदे ऑब्जेक्ट तुलना है, वास्तव में इसकी अनुशंसा नहीं करते हैं, लेकिन यह काम करता है।

    एक बेहतर समाधान है, और एक मैं के साथ इस्तेमाल किया है प्रतिक्रिया + फ्लक्स एक PropertyChanged bool लागू करने के लिए, और सिर्फ जांच लें कि आपका shouldComponentUpdate में है।

    अब, आपको चीजों को बदलने पर इसे स्थापित करने के बारे में जागरूक होने की आवश्यकता होगी, यानी, आपने ऑब्जेक्ट ग्राफ़ में कुछ गहरा बदल दिया है। संपत्ति कहें एक ऐसी संपत्ति वाला एक ऑब्जेक्ट है जो आपके हैंडल चेंज विधि में बदल जाता है।हालांकि आप चाहें इनपुट को मान्य करेंगे, फिर संपत्ति सेट करें = सत्य, और फिर आपको घटक DidUpdate लागू करने की आवश्यकता है। हम यहां एक धारणा बना रहे हैं, लेकिन यदि घटक अद्यतन किया गया है, तो आप संपत्ति को सेट पर वापस झूठ बोलते हैं ताकि आपके पास अवांछित अपडेट की कोई और ट्रिगरिंग न हो। मुझे उम्मीद है कि इसका कोई अर्थ है। यह एक तरह से अधिसूचना की तरह हैप्रॉपर्टी चेंज।

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

    http://jsfiddle.net/rpv9trhh/

    var e = { 
        prop1: 'test', 
        prop2: 'wee', 
        prop3: 'another property', 
        propFour: 'Oh yeah!' 
    }; 
    
    var FormComp = React.createClass({ 
        getInitialState: function(){ 
         return { 
          entity: this.props.entity 
         } 
        }, 
        render: function() { 
    
         var ent = this.state.entity; 
         var that = this; 
         var inputs = []; 
    
         for(var key in ent){ 
          inputs.push(<input 
           key={key} 
           style={{display:'block'}} 
           type="text" 
           ref={key} onChange={that._propertyChanged.bind(null, key)} 
           value={ent[key]} />) 
         } 
    
         return <form> 
          {inputs} 
          <input 
           type="button" 
           onClick={this._saveChanges} 
           value="Save Changes" /> 
         </form>; 
        }, 
        _propertyChanged: function(propName) { 
         var nextProp = this.refs[propName].getDOMNode().value; 
         var nextEntity = this.state.entity; 
         nextEntity[propName] = nextProp; 
    
         this.setState({ 
          entity: nextEntity 
         }); 
        }, 
        _saveChanges: function() { 
         var updatedEntity = this.state.entity; 
    
         for(var key in updatedEntity){ 
          alert(updatedEntity[key]); 
         } 
    
         //TODO: Call to service to save the entity, i.e.  
         ActionCreators.saveEntity(updatedEntity); 
        } 
    }); 
    
    React.renderComponent(<FormComp entity={e} />, document.body); 
    
    +1

    अपडेट: ऑब्जेक्ट्स के प्रदर्शन और आसान तुलना के संदर्भ में, आप http://facebook.github.io/immutable-js/ का लाभ भी ले सकते हैं। एक तरह की संपत्ति चेंज की गई चीज़ सुपर हैकी है, और केवल कुछ जो मैं पहले के साथ गड़बड़ कर दूंगा अधिक बेवकूफ प्रतिक्रिया और प्रवाह के लिए कोड को दोबारा करने का निर्णय लेना। – captray

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