我有一个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
就会被填充,然后一旦我继续,我就会看到数据:
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>
);
}
});
发布于 2014-09-19 23:45:10
这是因为来自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 });
当您使用调试器暂停脚本时,您为调用回调提供了扩展时间;当您继续时,数据已经到达并且看起来工作正常。
要修复此问题,您需要在数据从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)
编辑
如果这对您不起作用,请查看关于此问题的其他答案,这些答案解释了您的组件可能没有更新的其他原因。
发布于 2015-10-04 03:43:16
我想在此添加一个非常简单,但很容易犯的错误:
this.state.something = 'changed';
..。然后不明白为什么它没有呈现,谷歌搜索和出现在这个页面上,只是意识到你应该写下:
this.setState({something: 'changed'});
React仅在使用setState
更新状态时触发重新渲染。
发布于 2021-05-02 15:57:17
我的场景有点不同。我想很多像我这样的新手都会被难住--所以在这里分享。
我的状态变量是一个使用useState管理的JSON对象数组,如下所示:
const [toCompare, setToCompare] = useState([]);
但是,当使用下面的函数中的setToCompare更新toCompare时-重新渲染将不会触发。把它移到不同的组件上也不起作用。只有当其他事件触发re-render时,更新后的列表才会出现。
const addUniversityToCompare = async(chiptoadd) =>
{
var currentToCompare = toCompare;
currentToCompare.push(chiptoadd);
setToCompare(currentToCompare);
}
这就是我的解决方案。基本上-赋值数组就是复制引用- react不会将其视为更改-因为对数组的引用并没有更改-只是其中的内容。因此,在下面的代码中-只是使用slice复制了数组-没有任何更改-并在mods之后将其分配回来。工作得很好。
const addUniversityToCompare = async (chiptoadd) => {
var currentToCompare = toCompare.slice();
currentToCompare.push(chiptoadd);
setToCompare(currentToCompare);
}
希望这对像我这样的人有帮助。任何人,如果你觉得我错了,请让我知道--或者有其他方法。
提前谢谢。
https://stackoverflow.com/questions/25937369
复制相似问题