2015-06-11 17 views
160

मैं दस्तावेज के अनुभाग पढ़ रहा हूं और onChange उपयोग (JSBIN) का प्रदर्शन करने के लिए बस इस कोड को आजमाया।क्यों प्रतिक्रिया सेट कॉल करना स्टेटस विधि तुरंत राज्य को म्यूट नहीं करता है?

var React= require('react'); 

var ControlledForm= React.createClass({ 
    getInitialState: function() { 
     return { 
      value: "initial value" 
     }; 
    }, 

    handleChange: function(event) { 
     console.log(this.state.value); 
     this.setState({value: event.target.value}); 
     console.log(this.state.value); 

    }, 

    render: function() { 
     return (
      <input type="text" value={this.state.value} onChange={this.handleChange}/> 
     ); 
    } 
}); 

React.render(
    <ControlledForm/>, 
    document.getElementById('mount') 
); 

जब मैं ब्राउज़र में <input/> मान अपडेट करें, दूसरे console.loghandleChange कॉलबैक प्रिंट एक ही value पहले console.log, मैं क्यों this.setState({value: event.target.value}) का परिणाम handleChange कॉलबैक के दायरे में नहीं देख सकते हैं अंदर?

उत्तर

322

प्रतिक्रिया के documentation से:

setState() तुरंत this.state उत्परिवर्तित नहीं करता, लेकिन एक लंबित स्थिति संक्रमण पैदा करता है। इस विधि को कॉल करने के बाद this.state तक पहुंचने से संभावित रूप से मौजूदा मान वापस आ सकता है। setState पर कॉल के सिंक्रोनस ऑपरेशन की गारंटी नहीं है और कॉल प्रदर्शन लाभ के लिए बैच किए जा सकते हैं।

यदि आप राज्य परिवर्तन के बाद किसी फ़ंक्शन को निष्पादित करना चाहते हैं, तो इसे कॉलबैक के रूप में पास करें।

this.setState({value: event.target.value}, function() { 
    console.log(this.state.value); 
}); 
+0

अच्छा जवाब। मुझे जो अवलोकन करना है वह वैल्यूलिंक का उपयोग करने के लिए सावधान रहना है। यदि आपको इनपुट को प्रारूपित/मास्क करने की आवश्यकता नहीं है तो यह अच्छा काम करता है। – Dherik

+2

बिल्कुल सही। किसी भी तरह से मैं पूरी तरह से चूक गया था एक कॉलबैक तर्क था। –

+15

आप 'घटकDidUpdate' को भी देखना चाहेंगे। राज्य बदल जाने के बाद इसे बुलाया जाएगा। – Keysox

18

प्रतिक्रिया दस्तावेज में उल्लेख किया है, वहाँ setState की कोई गारंटी नहीं, तुल्यकालिक निकाले जाने के तो अपने console.log इसे अपडेट करने के लिए पहले राज्य वापस आ सकते हैं है।

माइकल पार्कर setState के भीतर कॉलबैक पास करने का उल्लेख करता है। राज्य परिवर्तन के बाद तर्क को संभालने का एक और तरीका componentDidUpdate जीवन चक्र विधि के माध्यम से है, जो कि प्रतिक्रिया दस्तावेज़ों में अनुशंसित विधि है।

आम तौर पर हम इस तरह के तर्क के लिए घटकडिडअपडेट() का उपयोग करने की सलाह देते हैं।

यह विशेष रूप से उपयोगी होता है जब setState को निकाल दिया जा सकता है, और आप प्रत्येक राज्य परिवर्तन के बाद एक ही कार्य को आग लगाना चाहते हैं। प्रत्येक setState पर कॉलबैक जोड़ने की बजाय, यदि आप आवश्यक हो तो विशिष्ट तर्क के साथ componentDidUpdate के अंदर फ़ंक्शन को स्थानांतरित कर सकते हैं।

// example 
componentDidUpdate(prevProps, prevState) { 
    if (this.state.value > prevState.value) { 
    this.foo(); 
    } 
} 
+0

उत्तर स्वीकार किया जाना चाहिए। – vikash

3

यहाँ प्रतिक्रिया डॉक्स कहना है:

कभी this.state सीधे उत्परिवर्तित, setState बुला के रूप में() बाद में उत्परिवर्तन आपके द्वारा किए गए जगह ले सकती। इस तरह से इलाज करें जैसे कि यह अपरिवर्तनीय था।

सेटस्टेट() तुरंत इस.स्टेट को म्यूटेट नहीं करता है लेकिन लंबित स्थिति संक्रमण बनाता है। इस विधि को कॉल करने के बाद this.state तक पहुंचने से संभावित रूप से मौजूदा मान वापस कर सकता है।

सेटस्टेट पर कॉल के सिंक्रोनस ऑपरेशन की कोई गारंटी नहीं है और पर कॉल प्रदर्शन प्रदर्शन के लिए बैच किया जा सकता है।setState() हमेशा एक प्रस्तुत करेगा जब तक सशर्त प्रतिपादन तर्क में लागू होना चाहिए, कॉम्पोनेंट अपडेट()।

परिवर्तनशील वस्तुओं का इस्तेमाल किया जा रहा है और तर्क shouldComponentUpdate() में लागू नहीं किया जा सकता है, बुला setState() केवल जब नए राज्य पहले वाली स्थिति से अलग अनावश्यक से बचने जाएगा फिर से बना देता है।

+0

क्या आप अपने उत्तर में दस्तावेज़ में एक लिंक जोड़ सकते हैं? धन्यवाद। – Pang

0

ठीक है, तो गूंगा soloution, लेकिन शायद यह किसी ऐसे व्यक्ति की मदद कर सकता है जो फॉलबैक से परिचित नहीं है। मेरे मामले में मैंने temp चर का उपयोग करके समस्या हल की।

मेरे पास उपयोगकर्ता के लिए परीक्षण है और मैं परीक्षण की स्थिति में उन्हें सहेजने वाले प्रश्नों के सही उत्तरों की संख्या की गणना कर रहा हूं और अंतिम प्रश्न के उत्तर के बाद मैं तुरंत राज्य से सही उत्तरों की संख्या प्रदर्शित करना चाहता था। हालांकि राज्य पुराने मूल्य को वापस कर रहा था। तो मैंने यह किया:

const numberOfCorrectQuestionsTemp = this.state.numberOfCorrectQuestions; 
if (questionCorrect) { 
    numberOfCorrectQuestionsTemp++; 
} 
this.setState({ 
    numberOfCorrectQuestions: numberOfCorrectQuestionsTemp, 
}); 
if (isLastQuestion) { 
    // display the result in percentage - with actual new value 
    alert((100/(this.state.numberOfQuestions)) * numberOfCorrectQuestionsTemp + '%'); 
} 

लेकिन कॉलबैक का उपयोग करने के लिए असीमित क्रिया के बाद कुछ करने का बेहतर समाधान है। आप इसे यहां पा सकते हैं: When to use React setState callback

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