2014-09-19 31 views
17

पर पुनः प्रतिपादन नहीं कर रहा है मेरे पास एक प्रतिक्रिया कक्षा है जो सामग्री प्राप्त करने के लिए एक एपीआई पर जा रही है। मैंने पुष्टि की है डेटा वापस आ रहा है, लेकिन यह फिर से प्रतिपादन नहीं:प्रतिक्रिया घटक राज्य परिवर्तन

var DealsList = React.createClass({ 
    getInitialState: function() { 
    return { deals: [] }; 
    }, 
    componentDidMount: function() { 
    this.loadDealsFromServer(); 
    }, 
    loadDealsFromServer: function() { 
    var newDeals = []; 

    chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) { 
     newDeals = deals; 
    }); 

    this.setState({ deals: newDeals }); 
    }, 
    render: function() { 
    var dealNodes = this.state.deals.map(function(deal, index) { 
     return (
     <Deal deal={deal} key={index} /> 
    ); 
    }); 
    return (
     <div className="deals"> 
     <table> 
      <thead> 
      <tr> 
       <td>Name</td> 
       <td>Amount</td> 
       <td>Stage</td> 
       <td>Probability</td> 
       <td>Status</td> 
       <td>Exp. Close</td> 
      </tr> 
      </thead> 
      <tbody> 
      {dealNodes} 
      </tbody> 
     </table> 
     </div> 
    ); 
    } 
}); 

हालांकि, अगर मैं जोड़ने के एक debugger नीचे की तरह, newDeals भर जाते हैं, और फिर एक बार मैं जारी, मैं डेटा देखें:

loadDealsFromServer: function() { 
    var newDeals = []; 

    chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) { 
     newDeals = deals; 
    }); 
    debugger 
    this.setState({ deals: newDeals }); 
    }, 

यह वही बुला सौदों सूची है:

var Gmail = React.createClass({ 
    render: function() { 
    return (
     <div className="main"> 
     <div className="panel"> 
      <DealsList person={this.props.person} /> 
     </div> 
     </div> 
    ); 
    } 
}); 

उत्तर

8

ऐसा इसलिए है क्योंकि chrome.runtime.sendMessage से प्रतिक्रिया अतुल्यकालिक है; यहां आपरेशन के आदेश है:

var newDeals = []; 

// (1) first chrome.runtime.sendMessage is called, and *registers a callback* 
// so that when the data comes back *in the future* 
// the function will be called 
chrome.runtime.sendMessage({...}, function(deals) { 
    // (3) sometime in the future, this function runs, 
    // but it's too late 
    newDeals = deals; 
}); 

// (2) this is called immediately, `newDeals` is an empty array 
this.setState({ deals: newDeals }); 

जब आप डीबगर के साथ स्क्रिप्ट को रोकते हैं, आप विस्तार समय कॉलबैक कॉल करने के लिए दे रहे हैं; जब तक आप जारी रखते हैं, डेटा आ गया है और ऐसा लगता है कि यह काम करता है।

सुलझाने के लिए आपको setState कॉल करने के लिए के बाद डेटा Chrome एक्सटेंशन से वापस आता है चाहता हूँ:

var newDeals = []; 

// (1) first chrome.runtime.sendMessage is called, and *registers a callback* 
// so that when the data comes back *in the future* 
// the function will be called 
chrome.runtime.sendMessage({...}, function(deals) { 
    // (2) sometime in the future, this function runs 
    newDeals = deals; 

    // (3) now you can call `setState` with the data 
    this.setState({ deals: newDeals }); 
}.bind(this)); 
+0

दुह! मुझे पता होना चाहिए था कि यह मामला तब था जब डीबगर लाइन ने इसे ठीक किया था। बाध्य (यह) वह चीज थी जब मैंने पहली बार इसका प्रयास किया था। धन्यवाद, महान विस्तृत टिप्पणी! – brandonhilkert

32

मैं इस की काफी आसान है, लेकिन ओह इतनी आसानी से बनाया गलती को जोड़ना चाहते हैं लेखन:

this.state.something = 'changed'; 

... और फिर समझ नहीं क्यों यह प्रतिपादन नहीं और Googling और इस पृष्ठ पर आ रहे हैं, केवल एहसास है कि आप लिखा जाना चाहिए था:

this.setState({something: 'changed'}); 

प्रतिक्रिया यदि आप setState का उपयोग राज्य को अद्यतन करने के लिए करते हैं तो केवल पुनः प्रस्तुत करना ट्रिगर करता है।

+0

यह वही समस्या है जो मैं कर रहा था। यह अजीब बात है कि वे प्रोप को अपडेट करने का प्रयास करते समय एक फेंकने के बाद चेतावनी नहीं देते हैं। – AndrewJM

+0

धन्यवाद अच्छा सर – heinst

+0

@AndrewJM वे एक चेतावनी फेंक नहीं सकते हैं। वे अगर आप 'this.state =' something 'लिखेंगे तो आप' राज्य 'के लिए सेटर को मार देंगे, लेकिन ऊपर दिए गए उदाहरण में, कोड गेटटर को हिट करता है, जो ऑब्जेक्ट देता है और फिर सेटिंग समाप्त होता है किसी ऑब्जेक्ट पर एक फ़ील्ड जो केवल राज्य की एक प्रति है। –

6

एक और ओह-आसान गलती, जो मेरे लिए समस्या का स्रोत था: मैंने अपना खुद का shouldComponentUpdate विधि लिखा था, जिसने मुझे जोड़ा गया नया राज्य परिवर्तन नहीं देखा।

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