रिएक्ट सेटस्टैट कॉलबैक का उपयोग कब करें


191

जब एक प्रतिक्रिया घटक स्थिति बदलता है, तो रेंडर विधि कहा जाता है। इसलिए किसी भी राज्य परिवर्तन के लिए, रेंडर मेथड बॉडी में एक क्रिया की जा सकती है। क्या तब सेटस्टैट कॉलबैक के लिए कोई विशेष उपयोग मामला है?


4
यह वर्तमान में स्पष्ट नहीं है कि आप क्या पूछ रहे हैं। क्या आप कुछ कोड शामिल कर सकते हैं?
डेविन ट्राटन

2
राज्य में DEFINITELYbeen को बदलने के बाद आप जो कुछ भी करना चाहते हैं उसके लिए setState कॉलबैक है। चूँकि setState async है, यदि आप एक fx को कॉल करना चाहते हैं और सुनिश्चित करें कि नया राज्य लोड है तो कॉलबैक के लिए यही है
Jayce444

3
सेटस्टेट कॉलबैक के लिए उपयोग का मामला काफी स्पष्ट है। जब आप कोई कार्य विशेष राज्य के अद्यतन होने के बाद चलाना चाहते हैं, तो आप इसका उपयोग करते हैं। यदि आप इस फ़ंक्शन को render()इसके स्थान पर रखते हैं, तो यह हर बार किसी भी राज्य को अपडेट किए जाने पर चलेगा, जो कि शायद आप नहीं चाहते हैं। यह आपके कोड को कम पठनीय और तार्किक भी बना देगा।
M3RS

जवाबों:


222

हाँ, setStateएक asynchronousतरह से काम करता है । इसका मतलब है कि चर को कॉल setStateकरने के बाद this.stateतुरंत नहीं बदला जाता है। इसलिए यदि आप एक राज्य चर पर राज्य की स्थापना के तुरंत बाद एक कार्रवाई करना चाहते हैं और फिर एक परिणाम लौटाते हैं, तो कॉलबैक उपयोगी होगा

नीचे दिए गए उदाहरण पर विचार करें

....
changeTitle: function changeTitle (event) {
  this.setState({ title: event.target.value });
  this.validateTitle();
},
validateTitle: function validateTitle () {
  if (this.state.title.length === 0) {
    this.setState({ titleError: "Title can't be blank" });
  }
},
....

उपरोक्त कोड उस तरह से काम नहीं कर सकता है जैसा कि titleवेरिएबल उस पर सत्यापन किए जाने से पहले नहीं किया गया है। अब आपको आश्चर्य हो सकता है कि हम render()फ़ंक्शन में ही सत्यापन कर सकते हैं, लेकिन यह बेहतर और साफ-सुथरा तरीका होगा यदि हम इसे परिवर्तन फ़ंक्शन में ही संभाल सकते हैं क्योंकि इससे आपका कोड अधिक व्यवस्थित और समझ में आता है

इस मामले में कॉलबैक उपयोगी है

....
changeTitle: function changeTitle (event) {
  this.setState({ title: event.target.value }, function() {
    this.validateTitle();
  });

},
validateTitle: function validateTitle () {
  if (this.state.title.length === 0) {
    this.setState({ titleError: "Title can't be blank" });
  }
},
....

एक और उदाहरण तब होगा जब आप चाहते हैं dispatchऔर जब राज्य बदल गया तो कार्रवाई करें। आप इसे कॉलबैक में करना चाहेंगे, न कि render()जैसा कि यह कहा जाता है कि हर बार पुनरावृत्ति होती है और इसलिए कई ऐसे परिदृश्य संभव हैं जहां आपको कॉलबैक की आवश्यकता होगी।

एक और मामला है API Call

जब आप किसी विशेष राज्य परिवर्तन के आधार पर एपीआई कॉल करने की आवश्यकता होती है, तो एक मामला उत्पन्न हो सकता है, यदि आप रेंडर विधि में ऐसा करते हैं, तो इसे हर रेंडर onStateपरिवर्तन पर कॉल किया जाएगा या क्योंकि कुछ प्रोप Child Componentपरिवर्तित हो गए हैं।

इस स्थिति में आप setState callbackएपीआई कॉल में अद्यतन राज्य मान को पारित करने के लिए एक का उपयोग करना चाहते हैं

....
changeTitle: function (event) {
  this.setState({ title: event.target.value }, () => this.APICallFunction());
},
APICallFunction: function () {
  // Call API with the updated value
}
....

3
मैं समझता हूं कि यह प्रकृति में अतुल्यकालिक है। मेरा सवाल यह था कि कुछ विशिष्ट है जो केवल सेटस्टेट कॉलबैक के लिए इस्तेमाल किया जा सकता है कि शायद रेंडर तरीके शरीर समर्थन नहीं कर सकते हैं (कुछ के अलावा चलो बेहतर कोड पठनीयता कहते हैं।)
साहिल जैन

@SahilJain सत्यापन सही उदाहरण है, आप इसे रेंडर () फ़ंक्शन में संभालना नहीं चाहेंगे क्योंकि तब इसे हर बार कहा जाएगा कि आप रेंडर में कोई भी बदलाव करते हैं () आप इसे तभी कॉल करना चाहेंगे जब केवल इनपुट में बदलाव हो और इसलिए समारोह में ही
शुभम खत्री

रेंडर के दौरान राज्य को बदलने के लिए प्रतिक्रिया को रोकें .. इसलिए कॉलबैक में सत्यापन डालने का अधिकार है।
webdeb

if (this.title.length === 0) {होना चाहिए this.state.title.length, है ना?
दिमित्री मिंकोवस्की

4
पहला उपयोग मामला शायद एक अच्छा विचार नहीं है। फिर से प्रस्तुत करने के बाद सेटस्टैट कॉलबैक ट्रिगर करते हैं, इसलिए आप बिना किसी अच्छे कारण के दोहरे रेंडर का कारण बन रहे हैं। यह बिल्कुल फ़ंक्शन तर्क (updater) का उद्देश्य है। आप बस चला सकते हैं setState(state => state.title.length ? { titleError: "Title can't be blank" } : null)और परिवर्तन ढेर हो जाएगा। कोई डबल रेंडर आवश्यक नहीं है।
R Esmond

46
this.setState({
    name:'value' 
},() => {
    console.log(this.state.name);
});

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

1
जब आप किसी फ़ंक्शन को कॉल करना चाहते हैं, तो स्थिति बदलने के बाद आप विधि का उपयोग कर सकते हैं।
आराजे बाबायेव

क्या होगा यदि आप नाम, फर्स्टनाम आदि जैसे राज्य के कई छिद्रों को सेट करना चाहते हैं?
सुमंत वरदा

44

1. usecase जो मेरे दिमाग में आता है, एक apiकॉल है, जिसे रेंडर में नहीं जाना चाहिए, क्योंकि यह eachराज्य परिवर्तन के लिए चलेगा । और एपीआई कॉल केवल विशेष राज्य परिवर्तन पर किया जाना चाहिए, और हर रेंडर पर नहीं ।

changeSearchParams = (params) => {
  this.setState({ params }, this.performSearch)
} 

performSearch = () => {
  API.search(this.state.params, (result) => {
    this.setState({ result })
  });
}

इसलिए किसी भी राज्य परिवर्तन के लिए, रेंडर मेथड बॉडी में एक क्रिया की जा सकती है।

बहुत बुरा अभ्यास , क्योंकि render-मैथोड शुद्ध होना चाहिए, इसका मतलब है कि कोई भी कार्य, राज्य परिवर्तन, एपीआई कॉल, प्रदर्शन नहीं किया जाना चाहिए, बस अपने विचार को मिलाएं और इसे वापस करें। कुछ घटनाओं पर ही कार्रवाई की जानी चाहिए। रेंडर एक घटना नहीं है, लेकिन componentDidMountउदाहरण के लिए।


25

सेटस्टैट कॉल पर विचार करें

this.setState({ counter: this.state.counter + 1 })

विचार

setState को async फ़ंक्शन में कहा जा सकता है

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

गलत कोड: डेटा के भ्रष्टाचार को जन्म देगा

this.setState(
   {counter:this.state.counter+1}
 );

सेटस्टैट के साथ सही कोड कॉल बैक फ़ंक्शन:

 this.setState(
       (prevState,props)=>{
           return {counter:prevState.counter+1};
        }
    );

इस प्रकार जब भी हमें अपनी वर्तमान स्थिति को अगले राज्य में अद्यतन करना होता है, तो अभी संपत्ति के मूल्य के आधार पर और यह सब async फैशन में हो रहा है, कॉलबैक फ़ंक्शन के रूप में setState का उपयोग करना अच्छा है।

मैंने इसे यहाँ कोड कोड में समझाने की कोशिश की है कोड पेन

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