मैं प्रतिक्रियाशील घटक को कैसे संचरित कर सकता हूं, जिसमें सभी परिवर्तनशील राज्य शामिल हैं?


93

मेरे पास कभी-कभी ऐसे घटक होते हैं जो वैचारिक रूप से राज्य के अनुकूल होते हैं जिन्हें मैं रीसेट करना चाहता हूं। आदर्श व्यवहार पुराने घटक को हटाने और एक नए, प्राचीन घटक को पढ़ने के बराबर होगा।

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

क्या ऐसा करने के लिए कोई एपीआई या पैटर्न है?

संपादित करें: मैंने this.replaceState(this.getInitialState())दृष्टिकोण का प्रदर्शन करते हुए एक तुच्छ उदाहरण बनाया और दृष्टिकोण के विपरीत this.setState(this.getInitialState()): jsfiddle - replaceStateअधिक मजबूत है।

जवाबों:


206

यह सुनिश्चित करने के लिए कि आपके द्वारा बताए गए अंतर्निहित ब्राउज़र स्थिति और बच्चों की स्थिति रीसेट है, आप रूट-कंपोनेंट घटक द्वारा लौटाए गए keyविशेषता को जोड़ सकते हैं render; जब यह बदलता है, तो उस घटक को फेंक दिया जाएगा और खरोंच से बनाया जाएगा।

render: function() {
    // ...
    return <div key={uniqueId}>
        {children}
    </div>;
}

व्यक्तिगत घटक की स्थानीय स्थिति को रीसेट करने के लिए कोई शॉर्टकट नहीं है।


1
जिज्ञासा से बाहर जब आप कहते हैं 'घटक को फेंक दिया जाएगा और खरोंच से बनाया जाएगा' तो क्या आपका मतलब है कि वर्चुअल डोम को फेंक दिया जाएगा और खरोंच से बनाया जाएगा लेकिन डोम अपडेट अभी भी अलग एल्गोरिथ्म के आधार पर होगा?
nimgrg

1
@nimgrg नहीं, असली DOM तत्वों को फिर से बनाया जाएगा। (वर्चुअल डोम पहले से ही हर रेंडर पर फिर से बनाया गया है, अगर आप असली डोम रखना चाहते हैं, तो बस keyइस मामले में सेट न करें।)
सोफी अल्परट

3
@EamonNerbonne रिएक्ट 0.8 पर, कुंजियों का उपयोग केवल एक ऐरे में सिबलिंग तत्वों के बीच अंतर करने के लिए किया जाता है और रूट पर ध्यान नहीं दिया गया। Github.com/facebook/react/issues/590 देखें ।
सोफी अल्परट

ध्यान दें replaceState()और getInitialState()दोनों नए ES6 वर्ग-शैली अभिकर्मकों में पदावनत हैं। this.setState(this._getInitialState())इसके बजाय उपयोग करें । इसके अलावा, आप अपने खुद के राज्य के शुरुआती समारोह का नाम नहीं दे सकते हैं getInitialState()- प्रतिक्रिया एक चेतावनी फेंकता है - इसे कुछ और कहें और स्पष्ट रूप state = this._getInitialState()से कक्षा के शीर्ष स्तर पर करें।
thom_nic

2
क्या एक घटक के अंदर से ऐसा करने का एक तरीका है, जिसमें बाहर की आवश्यकता के बिना एक प्रमुख प्रस्ताव पारित करना है?
त्रुक्त्र

14

आपको इसके बजाय वास्तव में बचना replaceStateऔर उपयोग करना चाहिए setState

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

प्रतिक्रिया में, यदि आपको सामान्यीकरण या विशेषज्ञता पर गलत करना है: विशेषज्ञता के लिए लक्ष्य। एक कोरोलरी के रूप में, आपके घटक के लिए राज्य के पेड़ में एक निश्चित पार्सिमनी होनी चाहिए (यदि आप ब्रांड-स्पैंकिंग नए उत्पाद को बाहर निकाल रहे हैं, तो इस नियम को बेहतर तरीके से तोड़ना ठीक है)।

वैसे भी यह आप कैसे करते हैं। ऊपर बेन के समान (स्वीकृत) उत्तर, लेकिन इस तरह:

this.setState(this.getInitialState());

इसके अलावा (बेन ने यह भी कहा) "ब्राउज़र स्थिति" को रीसेट करने के लिए आपको उस डोम नोड को हटाने की आवश्यकता है। वायड की शक्ति का दोहन करें और keyउस घटक के लिए एक नया प्रोप का उपयोग करें । नया रेंडर उस कंपोनेंट होलसेल की जगह लेगा।

संदर्भ: https://facebook.github.io/react/docs/component-api.html#replacestate


2
यह काम नहीं करेगा यदि वर्तमान स्थिति में कोई भी गुण शामिल हो जो प्रारंभिक अवस्था में नहीं है। जब तक मुझे विश्वास नहीं होता कि यह मामलों का एक महान "राज्य" है, जब तक कि आप किसी तरह इसे रोक नहीं सकते, मैं आश्चर्यजनक टूट से बचना चाहता हूं। मैं एक रीसेट के साथ ठीक हो जाऊंगा जो कुछ मामलों में दुर्घटनाग्रस्त हो जाता है, लेकिन एक रीसेट नहीं होता है जो आसानी से राज्य को भ्रष्ट कर देता है।
Eamon Nerbonne

निश्चित नहीं कि मैं अनुसरण करूं। क्या आप कह रहे हैं कि यह इसके बराबर नहीं है this.replaceState? कूज यह है।
wle8300

1
@ williamle8300 वे समतुल्य नहीं होंगे यदि एक नई संपत्ति को घटक जीवनचक्र में कॉल करने के लिए getInitialState()(ऑनक्लिक हैंडलर में) कहते हैं। इस मामले में, वह नई संपत्ति 2 के बाद भी मौजूद रहेगी getInitialState()
ग्राहम

@ ग्राहम मेरा मानना ​​है कि नए राज्य को एक ऐसे घटक से परिचित कराना बुरा है जो पहले से घोषित नहीं है getInitialState। फ़ंक्शन के शीर्ष पर JS फ़ंक्शन में अपने सभी चर घोषित करना बहुत पसंद है। साइड नोट: बेन अल्परट का समाधान मेरे समान है ... और वह एक आधिकारिक प्रतिक्रिया अनुरक्षक है!
wle8300

1
मुझे डर है कि फ़ंक्शन getInitialState (), और इसलिए जवाब, पदावनत है। एक अद्यतन अच्छा होगा।
मार्टिन आर।

8

keyउस तत्व में एक विशेषता जोड़ना जिसे आपको पुन: स्थापित करने की आवश्यकता है, इसे हर बार propsया stateतत्व परिवर्तन के सहयोगी को फिर से लोड करेगा ।

कुंजी = {नई तिथि ()। getTime ()}

यहाँ एक उदाहरण है:

render() {
  const items = (this.props.resources) || [];
  const totalNumberOfItems = (this.props.resources.noOfItems) || 0;

  return (
    <div className="items-container">
      <PaginationContainer
        key={new Date().getTime()}
        totalNumberOfItems={totalNumberOfItems}
        items={items}
        onPageChange={this.onPageChange}
      />
    </div>
  );
}

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