React组件不会在状态更改时重新渲染
问题描述:
我有一个React类,它将通过API来获取内容。我已确认该数据是回来了,但它不是重新渲染:React组件不会在状态更改时重新渲染
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>
);
}
});
答
这是因为从chrome.runtime.sendMessage
响应是异步的;这里是操作顺序:
当你用调试器暂停脚本时,你给了扩展时间来调用回调;当你继续时,数据已经到达,它似乎工作。
要解决,你想要做的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));
答
我想添加到这个的极大简单,但是是如此容易犯的错误写作:
this.state.something = 'changed';
...然后不明白为什么它不渲染和谷歌搜索,并在此页的到来,只有认识到,你应该写:
this.setState({something: 'changed'});
如果您使用setState
更新状态,则React仅触发重新呈现。
答
另一个非常容易的错误,这是我的问题的根源:我写了自己的shouldComponentUpdate
方法,它没有检查我添加的新状态更改。
呃!当调试器线修复它时,我应该知道这种情况。当我第一次尝试这个时,绑定(这个)是我错过的东西。谢谢,非常详细的评论! – brandonhilkert 2014-09-19 15:54:37