我有一个React类,它将通过API来获取内容。我已经确认数据又回来了,但是没有重新渲染:
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其填充,然后一旦我继续,我将看到数据:
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> ); } });
这是因为来自的响应chrome.runtime.sendMessage是异步的。操作顺序如下:
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扩展程序返回数据后进行通话:
setState
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)); // Don't forget to bind(this) (or use an arrow function)
[编辑]
If this doesn’t work for you, check out the other answers on this question, which explain other reasons your component might not be updating.