表单提交仅在第二次点击时提交,需要在ES6中回拨

时间:2018-04-02 11:59:19

标签: javascript reactjs ecmascript-6

单击“提交”会调用我的onSubmit函数,它会执行两项操作:

  1. formValidity(bool)的setState
  2. 提交表单
  3. 问题是第一次点击失败,第二次只提交。 我知道这是来自eval提交的,即使它还没有设置状态并且在第一次运行时失败。

    我希望onSubmit预先形成setStates,然后只需一次点击就可以预先形成eval来发送邮件。

    请注意:我已经尝试拆分功能并且结果相同。

    我假设这里有回调,但我不知道如何正确应用ES6。

    渲染元素:

    <button onClick={(event) => this.onSubmit(event)}>Submit</button>

    onSubmit函数:

    onSubmit = (event) => {
        event.preventDefault();
        if (!validator.isEmail(this.state.email)) {
            this.setState({
                errorType: this.state.formErrors["email"],
                formValidity: false
            })
        } else {
            this.setState({
                formValidity: true
            })
        }
        if (!validator.isAlpha(this.state.fName) || !validator.isAlpha(this.state.lName)) {
            this.setState({
                errorType: this.state.formErrors["name"],
                formValidity: false
            })
        } else {
            this.setState({
                formValidity: true
            })
        }
        if (this.state.formValidity === true) {
            console.log('mail sent!');
    
        } else {
            console.log('One of the inputs is erroneous');
    
        }
    
    }
    

    只是为了确保我解释得很好,我希望if (this.state.formValidity === true)仅在**所有其他条件eval&d; d并保持在相同的函数范围之后运行**。

    感谢, 芽

3 个答案:

答案 0 :(得分:2)

从按钮中删除事件处理程序并将其添加到表单元素:
<form onSubmit={this.handleOnSubmit}>并在构造函数中绑定this.handleOnSubmit

关于您的检查,我建议您在更改事件时对每个输入字段执行检查,并相应地更新状态。例如:

<input name="email" onChange={this.validateEmail}>

此(绑定)功能可以检查email字段,如果它有效且name字段有效,只需将this.formValidity状态更新为true。 / p>

然后,在您的handleOnSubmit函数中,删除除表单验证检查之外的所有内容。

编辑:
更改所有输入'onChange处理程序,以包含对特定函数的引用,该函数将对某些输入字段执行验证(并更新相应字段的值 - 如果您已使用该值)。例如(参考之前的输入字段):

validateEmail() {
   // Update input's state value
   // Perform validation for email input and update corresponding state
}

现在问题是,我建议你创建额外的状态属性(每个输入字段一个)来跟踪单个字段的有效性状态,如下所示:

this.state = {
  ...,
  fNameValid: false,
  lNameValid: false,
  emailValid: false,
  telValid: false,
}

现在,您的特定验证函数将仅更新与特定字段有关的状态,而不是整个表单(以及您的errorType):

validateEmail() {
   // Update input's state value

   if (!validator.isEmail(this.state.email)) {
      this.setState({
        emailValid: false,
        errorType: this.state.formErrors["email"],
      })
   } else {
      this.setState({
        emailValid: true
      })
   }
}

最后,让您的onSubmit事件处理程序执行所有字段的检查:

handleOnSubmit() {
   let isFormValid = this.state.fNameValid
                  && this.state.lNameValid
                  && this.state.emailValid
                  && this.state.telValid;

   if (isFormValid) {
     console.log('mail sent!');
   } else {
     console.log('One of the inputs is erroneous');
   }
}

状态formValidity属性最终变得多余。

答案 1 :(得分:1)

你需要从州测试formValidity的价值吗?如果不是,则if (this.state.formValidity === true)过度,您可以重新构建逻辑,以便setState的异步性更容易解释 - 例如:

onSubmit = event => {
  event.preventDefault()

  let formValidity = true
  let errorType = undefined

  if (!validator.isEmail(this.state.email)) {
    formValidity = false
    errorType = this.state.formErrors.email
  } else if (!validator.isAlpha(this.state.fName) || !validator.isAlpha(this.state.lName)) {
    formValidity = false
    errorType = this.state.formErrors.name
  }

  if (!formValidity) {
    this.setState({
      formValidity,
      errorType
    }, () => console.log('Form is invalid'))
  } else {
    this.setState({
      formValidity,
      errorType
    }, () => console.log('Form is valid'))
  }
}

您还会看到我利用setState的回调,可以安全地假设只有在设置状态后才能运行。

答案 2 :(得分:0)

setState是一个异步函数,您可以添加邮件发送代码或依赖于formValidity = true的任何此类代码作为setState函数的回调,因此不需要最后一个if-else块。总是避免最后一个if-else阻塞,因为setState以异步方式运行。

this.setState({
        formValidity: true
    },function(){
        console.log("mail sent");
         //or any other code dependent on formValidity set to true.
    });