【问题标题】:How do I validate a checkout form in React?如何在 React 中验证结帐表单?
【发布时间】:2020-03-16 21:30:00
【问题描述】:

我正在尝试在 React 中实现结帐表单。该表格共有 4 个字段:姓名、CC 编号、CC 到期和 CVV。我正在使用一个库来验证不聚焦的每个字段。验证由 validationCallback 方法触发,该方法接受 3 个参数:字段、状态和消息。我想关闭每个输入的状态,并且每个状态只允许提交一次 === true。这是我的代码。

constructor(props) {
    super(props);
    this.state = {
      nameOnCard: '',
      errorMessage: '',
      showLoaderForPayment: '',
      collectJs: null,
      token: null,
      isPaymentRequestCalled: false,
      showErrorModal: false,
      paymentErrorText: '',
      disabled: true,
    };
  }

我的状态中有一个禁用的属性,我最初将其设置为 true。

validationCallback: (field, status, message) => {
          if (status) {
            this.setState({ errorMessage: '' });
          } else {
            let fieldName = '';
            switch (field) {
              case 'ccnumber':
                fieldName = 'Credit Card';
                break;
              case 'ccexp':
                fieldName = 'Expire Date';
                break;
              case 'cvv':
                fieldName = 'Security Code';
                break;
              default:
                fieldName = 'A';
            }
            if (message === 'Field is empty') {
              this.setState({ errorMessage: `${fieldName} ${message}` });
            } else {
              this.setState({ errorMessage: `${message}` });
            }
          }
        },

在上述方法中,如果每个字段的状态===true,我想将 disabled 设置为 false... 下面是我设置为 this.state.disabled 值的按钮。

<button
                className="continueBtn disabled"
                disabled={this.state.disabled}
                onClick={this.handleCardSubmit}
              >
                <span className="fa fa-lock" />
                &nbsp; Pay $
                {selectedPayment.amount}
              </button>

我希望这些代码足以帮助解决问题。如果需要,我可以提供更多文件。

【问题讨论】:

    标签: reactjs forms validation jsx


    【解决方案1】:

    据我了解,如果所有字段均已正确填写,即所有状态均为 true,则您希望将按钮设置为 NOT DISABLED。
    您可以做的是为每个字段维护一个布尔数组并更新该数组中的状态,即初始化一个长度 = 否的数组。字段(在您的情况下为 3)并将所有值设置为 false。 False 表示该字段尚未经过验证。

    this.state = {
      statusArray = [false, false, false] // For as many fields
    }
    

    然后在 validationCallback 中,将该字段的索引设置为 true 或 false,即如果您的验证库返回第二个字段状态为 true,则将 statusArray 设置为 [false, true, false]。
    只有当所有 3 个值都为真时,才会验证表单。因此,您可以遍历数组并检查数组是否将所有 3 个值都设为真。或者您可以使用逻辑 AND 运算符,该运算符仅在所有值都为真时才返回真(我在下面使用的方法)。
    对于按钮,

    <button disabled={this.checkDisable()}>
    
    checkDisable = () => {
      let temp = this.state.statusArray;
      let answer = true;
      for(int i=0;i<temp.length;i++)
        answer = answer && temp[i];
      return answer;  // Only returns true if all 3 values are true
    }
    

    我希望你现在明白了。

    【讨论】:

    • 您是否建议默认使用 false 字段对 statusArray 进行硬编码?我有 3 个字段
    • 是的,硬编码会将它们初始化为 false 并帮助您处理用例
    • 您是否可以详细说明您的答案?这没有多大意义。
    • 我已经编辑过了。如果你还是不明白,你能解释一下具体是哪一部分吗?
    • 谢谢.. 我能够使用上面的解决方案。
    【解决方案2】:

    您需要检查两件事,表格是否被触摸以及是否有任何错误。我不知道您使用的是什么库,但很可能它有一个属性,如果没有在每个输入字段中添加一个 onFocus 并在您的状态下添加一个已触摸的属性。由于它是计算值,因此您实际上并不需要处于您的状态的禁用属性。只需检查每个渲染是否已触摸表单以及是否有任何错误。

    state = {
    ...,
    touched: false,
    ...
    }
    
    handleFocus = () => this.setState({touched: true}) 
    
    render(){
      const disabled = !!(this.state.touched && this.state.errorCode)
      return(
      ...
      <input onFocus={this.handleFocus} ... />
      ...
      <button disabled={disabled}
      )
    }
    

    编辑:

    state = {
    ...
    validInputs: []
    }
    
    validationCallback: (field, status, message) => {
              if (status) {
                this.setState((state) => ({ errorMessage: '', validInputs: [... new Set([...state.validInputs, field])] }));
              } else {
        ...
        render(){
        const disabled = this.state.length < inputs.length // the number of the input fields
        return(
          ...
          <button disabled={disabled} > 
          ...
        )
    
    

    【讨论】:

    • 我正在使用供应商提供的库。每个输入字段都在其末端进行验证。一旦每个字段都失焦,它们就是一个发送给它们的回调,它们会验证该字段。在每次验证时,它们都会返回一个布尔值状态。如果每个按钮的状态为真,我只希望启用提交按钮。有三个输入。这些输入是 ccnumber、ccexp 和 cvv。
    • 感谢您的澄清。在这种情况下,我建议您使用类似于 PiNaKa30 的答案。您可以在状态中再添加一个字段,例如validInputs。在验证回调函数中,如果输入字段名称不存在,则将其添加到 validInputs 数组。在重新渲染时检查 validInputs 长度是否与输入的长度相同
    猜你喜欢
    • 1970-01-01
    • 2013-10-17
    • 2022-06-13
    • 2019-02-22
    • 2017-09-25
    • 2019-01-18
    • 2021-11-15
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多