从componentDidUpdate尝试反向数据流时的无限循环

时间:2016-05-26 09:08:38

标签: reactjs

我有一个复选框组维护一个状态变量,其中包含所有当前选中的复选框,当用户检查一个框时,我将已检查值列表从componentDidUpdate()传递给父组件,使用该列表执行ajax调用设置一个柜台。但这引发了一个无限循环,我不明白为什么。

以下是代码: var CheckBoxGroup = React.createClass({

getInitialState : function(){
    var states = {};
    var that = this;
    _.map(this.props.defaultValues.checkboxes, function (choice, key) {
        states[key] = choice.checked;
    });
    return states;
},

componentDidUpdate: function () {
    console.log("component updated!");
    this.getCheckedValues();
},

componentWillUpdate : function(){
    console.log("component will update!");
    //this.getCheckedValues();

},

componentWillReceiveProps : function(nextProps){
    console.log("componentRecievedProps!!!!!!!!");
},

getCheckedValues: function () {
    var checkedObjArray = [];
    var self = this;

    // console.log("state",self.state);

    var checkedArray = _.filter(_.keys(this.state), function (key) {
        return self.state[key]
    });

     this.props.updateCount(checkedArray);
     //console.log("CheckboxFieldGroup.getCheckedValues() = " + checkedArray);
},

handleCheckBoxChange: function(prevState,nextState){
    var stateChanged = {};
    stateChanged[prevState] = nextState;
    //console.log("stateChanged",stateChanged);
    this.setState(stateChanged);  // Automatically triggers render() !!
},

renderChoices: function(){
    var that = this;
    let choices = _.map(this.props.defaultValues.checkboxes,function(choice,key){
        var props = {key : key, values : {name: this.props.defaultValues.name,value:key,label:choice.label}, onNewTick:this.handleCheckBoxChange};
        // console.log(props);
        return <CheckBox {...props} />;
}.bind(this));
return choices;

},

var SideBar = React.createClass({

getInitialState: function(){
    return {total_count : 0};
},

componentDidMount : function(){
    this.getAirportDetails([]);
},

getAirportDetails: function(args){
    console.log("Arguments",args);
    var url = "/airportdetails_list/"
    var new_url = _.reduceRight(args,function(a,b){
            return a+b+"/";
    },url);

    console.log("formatted url",new_url);
    $.ajax({
        url: new_url,
        dataType: "json",
        type: 'GET',
        headers: { 'Api-User-Agent': 'Example/1.0' },
        success: function(data) {
             console.log(data);
            this.setState({total_count:data.length});
        }.bind(this),
        error: function(xhr,err){
            console.error("Error occured file fetching!");
            console.error("Error occured ",err);
            console.error(xhr.responseText);

        }

    });

},


render: function() {

    var checkboxes = ['All','Civil Airports','Military Airport','Harbours','Airports','Railway Stations','Sea Plane Base'];
    var radiobuttons = ['Elevation','DirectFlight','Rating'];

    let checkBoxItems = checkboxes.map(function(text){
        return (<CheckBox displayText={text}  onNewTick={this.handleCheckBoxChange}/>);
    },this);
    let radioButtonItems = radiobuttons.map(function(text){
        return (<RadioButton displayText={text} value={text.toLowerCase()} />);
    });

    return (
        <div className="span3"  >
            <div className="well sidebar-nav custom-hero">
                <ul className="nav nav-list">
                    <li className="nav-header">Type</li>
                   <CheckBoxGroup defaultValues={defaults} updateCount={this.getAirportDetails} />
                    <li className="nav-header">Sort By</li>
                    {radioButtonItems}
                </ul>
            </div>
            <div className="alert alert-success" role="alert">Total Airports <span className="badge">{this.state.total_count}</span></div>;
        </div>
    );

}

});

1 个答案:

答案 0 :(得分:0)

您的componentDidUpdate会触发执行与props一起传递的功能。此函数在setState组件中执行SideBar,因此也会更新其所有子组件=&gt; componentDidUpdate再次触发CheckBoxGroup。这会导致循环。

更好的解决方案是在handleCheckBoxChange处理程序中启动它。

handleCheckBoxChange: function(prevState, nextState) {
  var stateChanged = {};
  stateChanged[prevState] = nextState;
  // call getCheckedValues as callback of setState
  this.setState(stateChanged, this.getCheckedValues);
},

getCheckedValues: function() {
  var checkedArray = _.filter(_.keys(this.state), (key) => {
            return this.state[key]
  });    
  this.props.updateCount(checkedArray);
},