如何在React中基于多个状态禁用按钮?

时间:2016-09-09 00:55:38

标签: javascript reactjs

我正在使用React构建表单,并且我希望在表单不是“有效”时禁用按钮,即当其中一个状态为空时。该按钮查看名为disable_button的状态。这就是我到目前为止所拥有的:

var MyForm = React.createClass({
  getInitialState: function() {
    return {
      group_id: '',
      ls_type_id: '',
      disable_button: false
    };
  },
  handleGroupChange: function(e) {
    this.setState({group_id: e.target.value});
  },
  handleTypeChange: function(e) {
    this.setState({ls_type_id: e.target.value});
  },
  handleClick: function() {
    console.log('Button clicked');
  },
  componentDidUpdate: function() {
    this.isFormValid();
  },
  isFormValid: function(){
    if (this.state.group_id == '' || this.state.ls_type_id == '') {
      this.setState({disable_button: true});
    } else {
      this.setState({disable_button: false});
    }
  },
  render: function() {
    return (
      <div>
        <select className='form-control' value={this.state.group_id} onChange={this.handleGroupChange}>
          <option value=''>Select group...</option>
          <option value='10'>Some group</option>
        </select>
        <br /> 
        <select className='form-control' value={this.state.ls_type_id} onChange={this.handleTypeChange}>
          <option value=''>Select type...</option>
          <option value='11'>Some type</option>
        </select>
        <br />
        <button className="btn btn-primary" onClick={this.handleClick} disabled={this.state.disable_button}>Save</button>
      </div>
    );
  }
});

ReactDOM.render(<MyForm />, document.getElementById('content'));

运行此代码会生成Uncaught RangeError: Maximum call stack size exceeded并且我意识到原因:它是因为在组件更新后,它会调用我的componentDidUpdate,然后更新状态,然后更新组件,并发生循环。所以我真的不知道如果其中一个状态为空白,我怎么能禁用该按钮。我可能会添加更多表单字段,因此我不想对其进行硬编码以仅查看这两个选项。

2 个答案:

答案 0 :(得分:3)

componentDidUpdate传递了两个道具,prevPropsprevStatedocumented。如果componentUpdateisFormValid发生了更改,您可以在type_id中使用此事实来仅调用ls_type_id

但是,级联的setState调用效率不高。在渲染函数中确定disable_button可能更有意义,因为您似乎没有在其他任何地方使用它。因此,删除isFormValid以及对它的所有调用,并将其放在render的开头:

render: function () {
  var disable_button = false;
  if (this.state.group_id == '' || this.state.ls_type_id == '') {
    disable_button = true;
  }
  return ( <div> ...content </div>
}

答案 1 :(得分:3)

请改为尝试:

isFormValid: function(){
  return this.state.group_id == '' || this.state.ls_type_id == '';
}

...

<button disabled={this.isFormValid()} ...>