【问题标题】:Infinite Loop when trying inverse data flow from componentDidUpdate尝试来自 componentDidUpdate 的反向数据流时出现无限循环
【发布时间】:2016-05-26 09:08:38
【问题描述】:

我有一个复选框组,它维护一个包含所有当前选中复选框的状态变量,当用户选中一个框时,我将选中的值列表从 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>
    );

}

});

【问题讨论】:

    标签: reactjs


    【解决方案1】:

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

    更好的解决方案是在您的 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);
    },
    

    【讨论】:

    • 我也是这么想的,但是这个组件实际上并没有改变,所以在渲染这个组件时 React 应该保持组件不变?
    猜你喜欢
    • 1970-01-01
    • 2021-08-26
    • 2021-07-12
    • 1970-01-01
    • 2016-10-22
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多