【问题标题】:How to disable a button when the state or the input value gets changed in React JS?当 React JS 中的状态或输入值发生更改时,如何禁用按钮?
【发布时间】:2018-08-14 21:35:33
【问题描述】:

我有一个包含大量输入和更新按钮的表单。我正在寻找禁用按钮的最佳方法,除非状态或输入之一发生更改。我知道让布尔状态变量保持按钮的禁用/启用状态的方式。然后在输入字段设置值相应地更改为状态变量名称时。

因为我有很多州。我需要编写一个循环遍历嵌套对象并进行比较的代码。

感谢您的帮助

【问题讨论】:

  • 我有,但代码很多。不知道你想不想看
  • 我正在尝试发布它,但有字符限制。有没有其他方法可以发给你?
  • 当您说“禁用按钮”时,您的意思是,根据表单字段是否全部填写,启用/禁用提交按钮?
  • 如果其中一个已填满,我希望按钮启用。

标签: javascript reactjs button onchange


【解决方案1】:

我不明白为什么 boolean 方法会不好。

无论如何,您可以使用 lodash _.isEqual 函数将之前的模型对象与当前状态进行比较,以检查数据是否已更改。

更新(sn-p):

class App extends React.Component {
  state = {
    foo: '',
    bar: ''
  }
  
  componentDidMount() {
    const { foo, bar } = this.props;
    this.setState({ foo, bar });
  }
  
  hasChangedSinceInitialState = () => {
    const { foo, bar } = this.props;
        
    // here you could use lodash ._isEqual if you have an bigger object
    return (foo === this.state.foo && bar === this.state.bar);
  }
  
  handleInputChange = (event) => {
    this.setState({ [event.target.name]: event.target.value });
  }
  
  render() {
    return (<div>
      <div>Foo: <input type='text' name='foo' value={this.state.foo} onChange={this.handleInputChange} /></div>
      <div>Bar: <input type='text' name='bar' value={this.state.bar} onChange={this.handleInputChange} /></div>
      <button disabled={this.hasChangedSinceInitialState()}>Submit</button>
    </div>);
  }
}

ReactDOM.render(<App foo='oldFoo' bar='oldBar' />, document.getElementById('root'));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/isEqual.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='root'></div>

【讨论】:

  • 你能举个例子吗?
  • 当然。我已经用 sn-p 更新了我的答案。如果您对此有任何疑问,请告诉我。
【解决方案2】:

如果我正确理解您的情况和代码,那么您只对验证组件状态中的某些变量感兴趣。

您可以通过向组件添加以下方法来实现所需的验证行为:

getCustomValidation() {

  // Extract a list for validation on only the state fields that are 
  // relevance to the form validation
  const fieldsToValidate = [
    "ppvLimit",
    "securityCode",
    "primaryPhone",
    "secondaryPhone",
    "email",
    "billingAddressLine1",
    "billingAddressLine2",
    "billingAddressCity",
    "billingAddressTerritoryCode",
    "billingAddressPostalCode",
    "contactAddressLine1",
    "contactAddressLine2",
    "contactAddressCity",
    "contactAddressTerritoryCode",
    "contactAddressPostalCode",
    "authorizedUser1",
    "authorizedUser2",
    "authorizedUser3",
    "authorizedUser4"
  ];

  // Iterate each field to check to determine if field is valid
  for(const fieldToValidate of fieldsToValidate) {

    // Extract value for current field
    const value = this.state[ fieldToValidate ]

    // If value is "truthy" then return valid (true)
    if( !!value ) {
      return true
    }
  }

  // If none of the validation fields are valid, return false
  return false;
}

要利用这一点,您可以在您的渲染方法中更新提交组件,如下所示:

<Button primary disabled={ !this.getCustomValidation() } type="submit">
{ loading ? <div><LoadingIcon size="lg" /> Saving...</div> : "Update" }
</Button>

【讨论】:

  • 感谢您的回答,我在代码中使用了您的逻辑,但是当我尝试使用 console.log(getCustomValidation()) 时,我在更改任何字段之前得到了一堆真假。
  • 你确定getInitialState() 被正确调用了吗?如果是这样,getCustomValidation() 应该根据初始状态返回 false。这可能是由于nextProps 通过componentWillReceiveProps 从外部传递的。另请注意 console.log(getCustomValidation()) 不正确 - 它应该是 console.log(thisgetCustomValidation())
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 2021-09-15
  • 2021-05-15
  • 2020-07-18
  • 2023-03-03
  • 1970-01-01
  • 2021-10-05
  • 2019-07-19
相关资源
最近更新 更多