最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I disable a button based on multiple states in React? - Stack Overflow

programmeradmin1浏览0评论

I'm building a form with React and I wanted to disable a button when the form is not 'valid', i.e. when one of the states is blank. The button looks at a state called disable_button. Here's what I have so far:

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');
  },
  ponentDidUpdate: 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'));

Running this code results in an Uncaught RangeError: Maximum call stack size exceeded and I realize why: it's because after the ponent updates, it calls my ponentDidUpdate, which then updates a state, which then updates the ponent, and the loop occurs. So I don't really know how can I make the button disable when one of those states is blank. I might add more form fields so I didn't want to hardcode it to only look at these two selects.

I'm building a form with React and I wanted to disable a button when the form is not 'valid', i.e. when one of the states is blank. The button looks at a state called disable_button. Here's what I have so far:

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');
  },
  ponentDidUpdate: 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'));

Running this code results in an Uncaught RangeError: Maximum call stack size exceeded and I realize why: it's because after the ponent updates, it calls my ponentDidUpdate, which then updates a state, which then updates the ponent, and the loop occurs. So I don't really know how can I make the button disable when one of those states is blank. I might add more form fields so I didn't want to hardcode it to only look at these two selects.

Share Improve this question edited Sep 9, 2016 at 1:20 Alaa Ali asked Sep 9, 2016 at 0:55 Alaa AliAlaa Ali 9261 gold badge12 silver badges25 bronze badges 2
  • Just call the isFormValid method in the change handlers. You don't need a ponentDidUpdate method. – Matthew Herbst Commented Sep 9, 2016 at 1:05
  • 2 Any value that can be calculated during render, should be calculated during render. – Dan Prince Commented Sep 9, 2016 at 1:06
Add a ment  | 

2 Answers 2

Reset to default 4

Try this instead:

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

...

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

ponentDidUpdate has two props passed in to it, prevProps and prevState as documented. You could use this fact in ponentUpdate to only call isFormValid if either the type_id or ls_type_id has changed.

However, the cascading setState calls are a little inefficient. It might make more sense to determine disable_button in your render function, since you don't appear to be consuming it anywhere else. So, delete isFormValid and all calls to it, and put this in the beginning of render:

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

评论列表(0)

  1. 暂无评论