React:componentDidUpdate或render中的事件触发的Ajax调用创建无限循环

时间:2017-04-07 08:51:53

标签: javascript ajax reactjs

我有一个由事件(点击)触发的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>
        }
    }

});

1 个答案:

答案 0 :(得分:2)

因为当你执行setstate时,它会触发re-rendering组件。里面

ajaxCall : function(countryIso3) { // Ajax call which sets data
        $.ajax({
    // ... 
        });
    },

您正在使用setState设置状态变量中的数据,这将再次调用render,而render内部再次进行api调用,然后再次setState ......这就是无限循环的原因。

该问题的简单解决方案是在componentDidMount生命周期方法中进行api调用。

componentDidMount

  

componentDidMount()在组件出现后立即调用   安装。需要DOM节点的初始化应该放在这里。如果你   需要从远程端点加载数据,这是一个好地方   实例化网络请求。

Regrading State Update

  

不要直接改变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({
       // ... 
     });
 }