我有一个由事件(点击)触发的Ajax调用。它可以正常工作(它将填充一个表),但它只是一直在进行Ajax调用,最终会消耗掉不可持续的内存。
这里的问题是什么?我已经尝试将Ajax调用放在componentDidMount
中,但结果是一样的,如果它被触发,Ajax调用将会爆炸(每秒5-10次调用)。
我可以做一个黑客,只是计算并停在1,但这不是解决它的正确方法(我需要找到根本原因:))
示例代码:
let Sample = React.createClass({
getInitialState : function () {
return{
data: [],
};
},
ajaxCall : function(someValue) { // Ajax call which sets data
$.ajax({
// ...
});
},
renderTable(value, index) { // Populates the table
// ..
},
render : function () {
let tabledata = this.state.data;
if (tableData) {
this.ajaxCall(this.props.someValue); // This goes into an infinite loop
return (
<Popover id="popover-positioned-scrolling-left" title={this.props.someValue}>
<Table striped bordered condensed hover>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
<tbody>
{tableData.map(this.renderTable)}
</tbody>
</Table>
</Popover>
)
}
else {
return <div></div>
}
}
});
答案 0 :(得分:2)
因为当你执行setstate
时,它会触发re-rendering
组件。里面
ajaxCall : function(countryIso3) { // Ajax call which sets data
$.ajax({
// ...
});
},
您正在使用setState
设置状态变量中的数据,这将再次调用render
,而render
内部再次进行api
调用,然后再次setState
......这就是无限循环的原因。
该问题的简单解决方案是在componentDidMount
生命周期方法中进行api调用。
componentDidMount()在组件出现后立即调用 安装。需要DOM节点的初始化应该放在这里。如果你 需要从远程端点加载数据,这是一个好地方 实例化网络请求。
不要直接改变this.state,因为之后调用setState()可能 替换你所做的突变。把它当作状态对待 不可变的。
更新:
在onClick事件中执行api调用。
让我们说,你想点击任何文字来调用api,然后像这样写:
<p onClick={this.ajaxCall}>Click me to fetch the data</p>
ajaxCall : function(countryIso3) { // Ajax call which sets data
$.ajax({
// ...
});
}