如何根据 React 中的多种状态禁用按钮?
2016-09-09
7376
我正在使用 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 reached
,我意识到原因:这是因为组件更新后,它调用我的
componentDidUpdate
,然后更新状态,然后更新组件,然后循环发生。所以我真的不知道当其中一个状态为空白时如何禁用按钮。我可能会添加更多表单字段,所以我不想硬编码它只查看这两个选择。
2个回答
尝试这个:
isFormValid: function(){
return this.state.group_id == '' || this.state.ls_type_id == '';
}
...
<button disabled={this.isFormValid()} ...>
yoz
2016-09-09
componentDidUpdate
有两个 props 传入,
prevProps
和
prevState
,如
所述
。您可以在
componentUpdate
中使用此事实,仅在
type_id
或
ls_type_id
发生更改时调用
isFormValid
。
但是,级联 setState 调用效率有点低。在渲染函数中确定
disable_button
可能更有意义,因为您似乎没有在其他任何地方使用它。因此,删除
isFormValid
和对它的所有调用,并将其放在渲染的开头:
render: function () {
var disable_button = false;
if (this.state.group_id == '' || this.state.ls_type_id == '') {
disable_button = true;
}
return ( <div> ...content </div>
}
Drew Schuster
2016-09-09