React.js रूप घटकों में राज्य या रेफ का उपयोग करें?


116

मैं React.js से शुरू कर रहा हूं और मैं एक सरल रूप करना चाहता हूं लेकिन प्रलेखन में मैंने इसे करने के दो तरीके ढूंढे हैं।

पहले एक उपयोग कर रहा है Refs :

var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }
    // TODO: send request to the server
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
    return;
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

और दूसरा रिएक्ट घटक के अंदर स्थिति का उपयोग कर रहा है :

var TodoTextInput = React.createClass({
  getInitialState: function() {
    return {
      value: this.props.value || ''
    };
  },

  render: function() /*object*/ {
    return (
      <input className={this.props.className}
      id={this.props.id}
      placeholder={this.props.placeholder}
      onBlur={this._save}
      value={this.state.value}
      />
    );
  },

  _save: function() {
    this.props.onSave(this.state.value);
    this.setState({value: ''
  });
});

अगर कुछ मौजूद है, तो मैं दो विकल्पों के पेशेवरों और विपक्षों को नहीं देख सकता। धन्यवाद।


क्या मुझसे कोई चूक हो रही है? आप फॉर्म वैल्यू पाने के लिए इवेंट ऑब्जेक्ट का उपयोग क्यों नहीं करते हैं? यह पहली जगह में यहाँ एक फार्म का उपयोग करने का एकमात्र कारण लगता है। यदि आप डिफॉल्ट सबमिट व्यवहार का उपयोग नहीं कर रहे हैं और इनपुट पर refs हैं, तो आपको उन्हें फ़ॉर्म में लपेटने की आवश्यकता नहीं है।
नक्षत्रसॉफ्ट

जवाबों:


143

संक्षिप्त संस्करण: Refs से बचें।


वे स्थिरता के लिए खराब हैं, और WYSIWYG मॉडल रेंडर प्रदान करने की सादगी का एक बहुत कुछ खो देते हैं।

आपके पास एक फॉर्म है। आपको एक बटन जोड़ना होगा जो फ़ॉर्म को रीसेट करता है।

  • refs:
    • डोम में हेरफेर करें
    • रेंडर बताता है कि फॉर्म 3 मिनट पहले कैसे देखा गया था
  • राज्य
    • setState
    • रेंडर बताता है कि फॉर्म कैसा दिखता है

आपके पास एक इनपुट में CCV नंबर फ़ील्ड और आपके एप्लिकेशन में कुछ अन्य फ़ील्ड हैं जो संख्याएँ हैं। अब आपको उपयोगकर्ता को लागू करने की आवश्यकता केवल संख्याओं में प्रवेश करती है।

  • refs:
    • एक onChange हैंडलर जोड़ें (क्या हम इससे बचने के लिए रेफ का उपयोग नहीं कर रहे हैं?)
    • अगर यह एक नंबर नहीं है, तो onChange में डोम में हेरफेर करें
  • राज्य
    • आपके पास पहले से ही एक ऑनचेंज हैंडलर है
    • यदि यह अमान्य है, तो एक कथन जोड़ें, और कुछ भी नहीं करें
    • रेंडर केवल तभी कहा जाता है जब वह एक अलग परिणाम प्रस्तुत करने जा रहा हो

एह, कोई बात नहीं, पीएम चाहते हैं कि अगर यह अमान्य है तो हम सिर्फ लाल बॉक्स-शैडो करें।

  • refs:
    • onChange हैंडलर को सिर्फ फोर्स यूडडेट या कुछ और कहें?
    • उत्पादन पर आधारित बनाने के लिए ... हुह?
    • हमें रेंडर में मान्य करने के लिए मूल्य कहां से मिलता है?
    • एक तत्व के className डोम संपत्ति को मैन्युअल रूप से हेरफेर करें?
    • मैं हार गया हूं
    • रेफरी के बिना फिर से लिखना?
    • रेंडर में डोम से पढ़ें अगर हम माउंटेड हैं तो मान्य मानें?
  • राज्य:
    • यदि कथन को हटा दें
    • इस के आधार पर वैधता प्रदान करें

हमें अभिभावक को वापस नियंत्रण देने की आवश्यकता है। डेटा अब प्रॉप्स में है और हमें बदलावों पर प्रतिक्रिया करने की आवश्यकता है।

  • refs:
    • कंपोनेंट को लागू करेंडिमाउंट, कंपोनेंटविलीपेड और कंपोनेंटडायडडेट
    • पिछले प्रॉप्स को मैन्युअल रूप से अलग करें
    • परिवर्तनों के न्यूनतम सेट के साथ डोम में हेरफेर करें
    • हे! हम प्रतिक्रिया में प्रतिक्रिया लागू कर रहे हैं ...
    • वहाँ अधिक है, लेकिन मेरी उंगलियों को चोट लगी है
  • राज्य:
    • sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js

लोगों को लगता है कि राज्य में रखने की तुलना में रेफ्स 'आसान' हैं। यह पहले 20 मिनट के लिए सही हो सकता है, यह उसके बाद मेरे अनुभव में सच नहीं है। अपने आप को यह कहने की स्थिति में रखें "हाँ, मैंने इसे 5 मिनट में किया होगा" के बजाय "श्योर, मैं सिर्फ कुछ घटकों को फिर से लिखूंगा"।


3
क्या आप sed -e / s / this.state / this.props / 's / handleChange / onChange /' -i form.js के बारे में थोड़ा और बता सकते हैं?
गैब्रिएलगुस्सी

1
नहीं, मेरा मतलब है कि डोम में वास्तविक परिवर्तन। React.findDOMNode(this.refs.foo)। यदि आप परिवर्तन करते हैं तो this.refs.foo.props.barकुछ नहीं होगा।
ब्रिगैंड

1
उदाहरण के लिए, यदि आपने इसे <input onChange={this.handleChange} value={this.state.foo} />बदल दिया है <input onChange={this.props.handleChange} value={this.props.foo} />, या प्रॉप्स में कॉलबैक (एस) को कॉल करने के लिए अपने हैंडकॉन्च फ़ंक्शन (एस) को संशोधित कर रहे हैं। किसी भी तरह से, यह कुछ छोटे स्पष्ट परिवर्तन है।
ब्रिगैंड

4
यकीन नहीं होता कि मैं केवल एक ही हूँ जो आपके उत्तर को थोड़ा भ्रमित कर रहा है। क्या आप अपने कोड को स्पष्ट करते हुए कुछ कोड नमूने दिखा सकते हैं?
ऋषभ

2
स्क्रीन पर 50+ इनपुट होने से किसी भी राज्य परिवर्तन पर प्रत्येक प्रतिपादन अवांछनीय है। प्रत्येक inputक्षेत्र की संरचना करना जहां प्रत्येक अपनी स्वयं की स्थिति को बनाए रखता है आदर्श है। कुछ बिंदु पर हमें इन विभिन्न स्वतंत्र राज्यों को कुछ बड़े मॉडल के साथ सामंजस्य बनाने की आवश्यकता है। हो सकता है कि हमारे पास टाइमर पर एक ऑटोसैव हो, या हम बस componentWillUnmountइस पर सहेजते हैं कि यह वह जगह है जहां मैं refsआदर्श पाता हूं , सामंजस्य के दौरान हम stateप्रत्येक से मूल्य को लूटते हैं ref, और कोई भी समझदार नहीं है। मैं मानता हूं कि ज्यादातर मामलों stateमें जवाब है, लेकिन एक बड़ी संख्या के साथ inputs, एक उचित refsपैटर्न का उपयोग एक प्रदर्शन वरदान है
लक्स

105

मैंने कुछ लोगों को उपरोक्त उत्तर को "कभी रेफ्स का उपयोग नहीं करने" के कारण के रूप में उद्धृत किया है और मैं अपनी (साथ ही कुछ अन्य रिएक्ट देवों के बारे में भी बात कर रहा हूं) को राय देना चाहता हूं।

घटक उदाहरणों के लिए उनका उपयोग करने के बारे में बात करते समय "रेफरी का उपयोग न करें" भावना सही है। मतलब, आपको घटक उदाहरणों को हथियाने और उन पर कॉल करने के तरीकों के रूप में रेफ का उपयोग नहीं करना चाहिए। यह refs का उपयोग करने का गलत तरीका है और जब refs दक्षिण में जल्दी जाते हैं।

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

2019 संपादित करें: भविष्य के नमस्कार दोस्तों। कुछ वर्षों पहले मैंने जो भी उल्लेख किया था उसके अलावा ^, रिएक्ट हुक के साथ, रेफरी भी रेंडरर्स के बीच डेटा का ट्रैक रखने का एक शानदार तरीका है और केवल डोम नोड्स को हथियाने तक सीमित नहीं हैं।


3
आपका अंतिम पैराग्राफ सही अर्थ देता है, लेकिन क्या आप अपने दूसरे पैराग्राफ को स्पष्ट कर सकते हैं? एक घटक उदाहरण को हथियाने और एक विधि को कॉल करने का एक ठोस उदाहरण क्या है जिसे गलत माना जाएगा?
डैनी लीबिन

2
मैं इससे सहमत हूँ। मैं जब तक / जब तक मुझे किसी क्षेत्र के मान का सत्यापन या हेरफेर करने की आवश्यकता होती है, तब तक रिफ का उपयोग करता हूं। यदि मुझे प्रोग्रामेटिक रूप से मानों को बदलने या बदलने की आवश्यकता है, तो मैं राज्य का उपयोग करता हूं।
क्रिस्टोफर डेविस

1
मैं इस बात से भी सहमत हूं। एक खोज चरण के दौरान मैंने भोलेपन के साथ बड़ी संख्या में इनपुट के साथ जानबूझकर एक स्क्रीन से संपर्क किया है। सभी मानचित्र में (राज्य में) मानचित्र में संग्रहीत मूल्य। कहने की आवश्यकता नहीं है, राज्य की स्थापना और 50+ इनपुट (कुछ सामग्री-उई, जो भारी थे!) को प्रस्तुत करने के बाद से प्रदर्शन खराब हो गया था! चेकबॉक्स क्लिक के रूप में इस तरह के मामूली यूआई परिवर्तन आदर्श नहीं थे। प्रत्येक इनपुट को कंपोनेंटाइज़ करना जो अपनी स्थिति को बनाए रख सकता है उचित दृष्टिकोण लग रहा था। यदि सामंजस्य की आवश्यकता है, तो बस में सहकर्मी refsऔर राज्य मूल्य प्राप्त करें। यह वास्तव में एक बहुत अच्छा पैटर्न की तरह लगता है।
लक्स

2
मैं पूरी तरह से सहमत। स्वीकृत उत्तर मेरी राय में बहुत अस्पष्ट है।
जेम्स राइट

मैं सहमत हूँ। एक सामान्य प्रपत्र घटक को डिज़ाइन करते समय, यह नियंत्रित घटकों के दर्द बिंदुओं को प्रकाश में लाता है और फोकस, त्रुटि से निपटने आदि का प्रबंधन करता है। आवश्यकता पड़ने पर मुझसे बात करें। मैं अपने घटकों को refs में स्थानांतरित कर रहा हूं।
कुशाल्वम

6

टीएल; डीआर आम तौर पर बोलते हुए, refsरिएक्ट के घोषणात्मक दर्शन के खिलाफ जाते हैं , इसलिए आपको उन्हें अंतिम उपाय के रूप में उपयोग करना चाहिए। state / propsजब भी संभव हो उपयोग करें ।


यह समझने के लिए कि यो कहां refsबनाम का उपयोग करता है state / props, आइए कुछ ऐसे डिज़ाइन सिद्धांतों पर ध्यान दें, जो रिएक्ट का अनुसरण करते हैं।

प्रति प्रतिक्रिया प्रलेखन के बारे मेंrefs

ऐसी चीज़ों के लिए रेफ्स का उपयोग करने से बचें, जिन्हें घोषित रूप से किया जा सकता है।

एस्केप हैच के बारे में प्रति प्रतिक्रिया डिजाइन सिद्धांत

यदि कुछ पैटर्न जो ऐप्स बनाने के लिए उपयोगी हैं, तो घोषणात्मक तरीके से व्यक्त करना कठिन है, हम इसके लिए एक अनिवार्य एपीआई प्रदान करेंगे। (और वे यहाँ रेफरी से लिंक करते हैं)

इसका मतलब है कि रिएक्ट की टीम प्रतिक्रियाशील / घोषित तरीके से किसी भी चीज के लिए बचने refsऔर उपयोग करने का सुझाव देती है state / props

@ टायलर मैकगिनिस ने एक बहुत अच्छा जवाब दिया है , साथ ही कहा कि

रेफ का उपयोग करने का सही (और बहुत उपयोगी) तरीका तब है जब आप DOM से कुछ मूल्य प्राप्त करने के लिए उनका उपयोग कर रहे हैं ...

जब आप ऐसा कर सकते हैं, तो आप रिएक्ट के दर्शन के खिलाफ काम करेंगे। यदि आपके पास किसी इनपुट में मूल्य है, तो यह निश्चित रूप से आता है state / props। कोड को सुसंगत और पूर्वानुमेय रखने के लिए, आपको state / propsवहां भी रहना चाहिए । मैं इस तथ्य को स्वीकार करता हूं कि refsकभी-कभी आपको तेज समाधान मिलता है, इसलिए यदि आप अवधारणा का प्रमाण देते हैं, तो त्वरित और गंदा स्वीकार्य है।

यह हमें कई के साथ छोड़ देता है ठोस उपयोग के मामलों के लिएrefs

फोकस, टेक्स्ट चयन, या मीडिया प्लेबैक का प्रबंधन। अनिवार्य एनिमेशन को ट्रिगर करना। तृतीय-पक्ष DOM पुस्तकालयों के साथ एकीकरण।


5

यह पद पुराना है।

मैं उस मामले पर एक मामले पर अपने छोटे से अनुभव को साझा करूंगा।

मैं एक बड़े घटक (414 लाइनों) पर काम कर रहा था जिसमें बहुत सारे 'डायनेमिक' इनपुट और बहुत सारे कैश्ड डेटा शामिल थे। (मैं पृष्ठ पर अकेले काम नहीं कर रहा हूं, और मेरी इंद्रियां मुझे बताती हैं कि कोड की संरचना शायद बेहतर ढंग से विभाजित की जा सकती है, लेकिन यह बिंदु नहीं है (ठीक है, यह हो सकता है लेकिन मैं इसके साथ काम कर रहा हूं)

मैंने पहले इनपुट के मूल्यों को संभालने के लिए राज्य के साथ काम किया:

  const [inputsValues, setInputsValues] = useState([])
  const setInputValue = (id, value) => {
    const arr = [...inputsValues]
    arr[id] = value
    setInputsValues(arr)
  }

और निश्चित रूप से इनपुट्स में:

value={inputsValues[id] || ''}
onChange={event => setInputValue(id, event.target.value)}

प्रतिपादन इतना भारी था कि इनपुट परिवर्तन **** के रूप में तड़का हुआ था (कुंजी को नीचे रखने की कोशिश न करें, पाठ केवल एक विराम के बाद दिखाई देगा)

मुझे यकीन था कि मैं refs के इस्तेमाल से इससे बच सकता हूं।

इस तरह समाप्त हुआ:

  const inputsRef = useRef([])

और इनपुट्स में:

ref={input => (inputsRef.current[id] = input)}

[अच्छी तरह से मेरे मामले में इनपुट मटेरियल-यूआई टेक्स्टफिल्ड था इसलिए यह था:

inputRef={input => (inputsRef.current[id] = input)}

]

इसके लिए धन्यवाद, कोई रेंडरिंग नहीं है, इनपुट सुचारू है, funcionality उसी तरह काम करता है। यह चक्र और गणना को बचाएगा, इसलिए ऊर्जा भी। यह धरती के लिए करो)

मेरा निष्कर्ष: आदानों के मूल्य के लिए यूट्रीफ की जरूरत हो सकती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.