EmailJS + React Hooks + 'preventDefault' 问题

Issue with EmailJS + React Hooks + 'preventDefault'

我已经使用 React 几个月了,我决定尝试构建我的作品集。为此,我默认使用 Material UI 表单,以便使用 EmailJS 平台进行联系。我确信这很简单,但是我已经花了好几个小时来解决这个问题而没有找到解决方案。 不知道是Material UI Librarie 的'Custom Input' 还是onClick 事件相关的问题。 我的问题是未定义的“e.preventDefault”。 这可能很简单,但是为了尝试解决它,我想我最终变得头晕目眩,并且比开始时更加困惑。 谢谢!

这是带有表单验证器的代码:

    const [values, setValues] = useState({
        name: '',
        email: '',
        message: '',
  });
  const handleChange = (name)=> (e) => {
        setValues({ ...values, [e.target.id]: e.target.value });
  };

  const isFormValid = () => {
        if (!values.name || !values.email || !values.message) {

      return false;}
      else {
      return true;}

  };

  const sendEmail =(e) => {
    e.preventDefault()
    emailjs.sendForm('gmail', 'template_AILAIHUt', e.target, 'user_kPqhCaNpQHv75H92RjVhj')
      .then((result) => {
          console.log(result.text + 'funciona');
      }, (error) => {
          console.log(error.text + 'no funciona');
      });
  }

  const handleSubmit = (e) => {
        if (!isFormValid()) {
      //message of error in the screen, maybe sweet alerts
      console.log('falta algo')
    }
    else{ sendEmail(e)}
    };



  return (
    <div className={classes.section}>
      <div className={classes.container}>
        <GridContainer justify="center">
          <GridItem xs={12} sm={12} md={4}>
            <Card>
              <form className={classes.form}>
                <CardHeader style={{ fontWeight: "fontWeightBold" }} color='primary' className={classes.cardHeader}>
                  <h4>Let's create something together </h4>

                </CardHeader>
                <CardBody>
                  <CustomInput
                    labelText="Name..."
                    id="name"
                    required={true}
                    formControlProps={{
                      required: true,
                      fullWidth: true
                    }}
                    inputProps={{ 
                      required: true,
                      onChange: handleChange(),
                      id:'name',
                      value: values.name,
                      type: "text",
                      endAdornment: (
                        <InputAdornment position="end">
                          <People className={classes.inputIconsColor} />
                        </InputAdornment>
                      )
                    }}
                  />
                  <CustomInput
                    labelText="Email..."
                    id="email"
                    type='email'
                    required={true}
                    onChange={handleChange()}
                    formControlProps={{
                      required: true,
                      fullWidth: true
                    }}
                    inputProps={{
                      required: true,
                      onChange: handleChange(),
                      id:'email',
                      value: values.email,
                      type: "email",
                      endAdornment: (
                        <InputAdornment position="end">
                          <Email className={classes.inputIconsColor} />
                        </InputAdornment>
                      )
                    }}
                  />
                  <CustomInput
                    labelText="Be free..."
                    id="message"
                    required={true}
                    formControlProps={{
                      size: 'large', 
                      rows: '4',
                      required: true,
                      fullWidth: true
                    }}
                    inputProps={{
                      multiline: true,
                      required: true,
                      onChange: handleChange(),
                      id:'message',
                      value: values.message,
                      multiline: true,
                      type: "text",
                      endAdornment: (
                        <InputAdornment position="end">
                          <Icon className={classes.inputIconsColor}>
                            <SendIcon  className={classes.inputIconsColor}/>
                          </Icon> 
                        </InputAdornment>
                      ),
                      autoComplete: "off"
                    }}
                  />
                </CardBody>
                <CardFooter className={classes.cardFooter}>
                  <Button simple color="primary" size="lg" onClick={(e) => handleSubmit()}>
                    Submit
                  </Button> 
                </CardFooter>
              </form>
            </Card>
          </GridItem>
        </GridContainer>
      </div>
    </div>
  );
}

请确保添加您收到的错误或您的代码在什么时候停止工作,以便我们更好地了解问题所在。

我已经在你的代码中看到了一些问题,我将在下面修复它们并在每个修复上方写一个大注释,这样你就可以确定我在哪里更改了代码。

    const [values, setValues] = useState({
        name: '',
        email: '',
        message: '',
  });
  const handleChange = (name)=> (e) => {
        setValues({ ...values, [e.target.id]: e.target.value });
  };

  const isFormValid = () => {
        if (!values.name || !values.email || !values.message) {

      return false;}
      else {
      return true;}

  };

  const sendEmail = (e) => {
    emailjs.sendForm('gmail', 'template_AILAIHUt', e.target, 'user_kPqhCaNpQHv75H92RjVhj')
      .then((result) => {
          console.log(result.text + 'funciona');
      }, (error) => {
          console.log(error.text + 'no funciona');
      });
  }

  const handleSubmit = (e) => {
      // HERE: you always want to prevent default, so do this first
      e.preventDefault()
        if (!isFormValid()) {
           //message of error in the screen, maybe sweet alerts
           console.log('falta algo')
        } else{ 
          sendEmail(e)
        }
    };



  return (
    <div className={classes.section}>
      <div className={classes.container}>
        <GridContainer justify="center">
          <GridItem xs={12} sm={12} md={4}>
            <Card>
              <!-- HERE: use the FORM submit function and make sure to pass the event down to handleSubmit(e)@ -->
              <form className={classes.form} onSubmit={(e) => handleSubmit(e)}>
                <CardHeader style={{ fontWeight: "fontWeightBold" }} color='primary' className={classes.cardHeader}>
                  <h4>Let's create something together </h4>

                </CardHeader>
                <CardBody>
                  <CustomInput
                    labelText="Name..."
                    id="name"
                    required={true}
                    formControlProps={{
                      required: true,
                      fullWidth: true
                    }}
                    inputProps={{ 
                      required: true,
                      onChange: handleChange(),
                      id:'name',
                      value: values.name,
                      type: "text",
                      endAdornment: (
                        <InputAdornment position="end">
                          <People className={classes.inputIconsColor} />
                        </InputAdornment>
                      )
                    }}
                  />
                  <CustomInput
                    labelText="Email..."
                    id="email"
                    type='email'
                    required={true}
                    onChange={handleChange()}
                    formControlProps={{
                      required: true,
                      fullWidth: true
                    }}
                    inputProps={{
                      required: true,
                      onChange: handleChange(),
                      id:'email',
                      value: values.email,
                      type: "email",
                      endAdornment: (
                        <InputAdornment position="end">
                          <Email className={classes.inputIconsColor} />
                        </InputAdornment>
                      )
                    }}
                  />
                  <CustomInput
                    labelText="Be free..."
                    id="message"
                    required={true}
                    formControlProps={{
                      size: 'large', 
                      rows: '4',
                      required: true,
                      fullWidth: true
                    }}
                    inputProps={{
                      multiline: true,
                      required: true,
                      onChange: handleChange(),
                      id:'message',
                      value: values.message,
                      multiline: true,
                      type: "text",
                      endAdornment: (
                        <InputAdornment position="end">
                          <Icon className={classes.inputIconsColor}>
                            <SendIcon  className={classes.inputIconsColor}/>
                          </Icon> 
                        </InputAdornment>
                      ),
                      autoComplete: "off"
                    }}
                  />
                </CardBody>
                <CardFooter className={classes.cardFooter}>
                  <input type="submit" value="Submit" />
                </CardFooter>
              </form>
            </Card>
          </GridItem>
        </GridContainer>
      </div>
    </div>
  );
}

到目前为止最大的收获,您有点混淆了表单逻辑。表单依赖于输入类型的提交按钮。此外,将 onSubmit 函数与提交输入元素一起使用。

如果您想使用表单并阻止提交时的默认事件,您必须使用输入类型提交按钮和表单的 onSubmit 功能。由于这是一个 React 应用程序,并且您根本不依赖表单事件,因此您也可以采用不同的方式(并保留您的样式按钮)。请参阅 this guide 了解如何使用自定义按钮提交表单。

有同样的问题,通过将 id 添加到表单并将其传递给 emailJS 方法解决了这个问题。

将 form-id 添加到 emailjs 方法:

emailjs
  .sendForm(
    "service_<id>",
    "template_<id>",
    "#contact-form",
    "user_<id>"
  )

然后到表单标签:

id="contact-form"