You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React表单reCaptcha验证成功后错误提示异常问题

问题分析与修复方案

1. 移除重复的提交触发

按钮同时绑定了onClick={submitForm}和表单的onSubmit={handleSubmit(submitForm)},会导致提交逻辑被触发两次,直接移除按钮的onClick属性:

<button type="submit" href="#_">
  <span className="relative">SEND</span>
</button>

2. 统一使用react-hook-form进行表单验证

你当前混用了手动表单验证和react-hook-form的验证体系,导致错误提示无法正常触发。直接利用react-hook-form的能力处理验证,移除手动维护的formErrors和字段检查逻辑:

修改submitForm函数

const submitForm = (data) => {
  // 先检查reCaptcha是否验证通过
  if (!valid) {
    alert("Please verify you are not a robot");
    return;
  }

  // 验证通过且表单无错误,提交表单
  emailjs.sendForm(
    `${process.env.REACT_APP_SERVICE_ID}`,
    `${process.env.REACT_APP_TEMPLATE_ID}`,
    form.current,
    `${process.env.REACT_APP_PUBLIC_KEY}`
  )
  .then(() => {
    form.current.reset();
    alert('Enquiry Sent!');
    // 重置reCaptcha状态
    captchaRef.current.reset();
    setValid(false);
  })
  .catch(err => console.error('提交失败:', err));
};

完善验证规则与错误提示

给每个字段添加内置错误信息,并修正message字段的错误提示内容:

// 名字输入框
<input 
  className='contact-input' 
  type='text' 
  name='first-name' 
  placeholder='Your First Name'
  {...register("first-name", { 
    required: "Please enter your first name"
  })} 
/>
{errors['first-name'] && <div className="text-red-600">{errors['first-name'].message}</div>}

// 姓氏输入框
<input 
  className='contact-input' 
  type='text' 
  name='last-name' 
  placeholder='Your Last Name'
  {...register("last-name", { 
    required: "Please enter your last name"
  })} 
/>
{errors['last-name'] && <div className="text-red-600">{errors['last-name'].message}</div>}

// 邮箱输入框
<input 
  className='contact-input' 
  type='email' 
  name='email' 
  placeholder='Your Email Address'
  {...register("email", {
    required: "Please enter your email address",
    pattern: {
      value: /^\S+@\S+$/i, 
      message: "Please enter a valid email address"
    }
  })}
/>
{errors['email'] && <div className="text-red-600">{errors['email'].message}</div>}

// 消息输入框
<textarea 
  className='border-black border rounded-md block sm:w-1/2 mobile:w-5/6 tablet:w-full pl-2 resize-none hover:placeholder-gold placeholder:text-center mobile:text-base' 
  name="message" 
  rows="4" 
  placeholder='Message' 
  maxLength="6000"
  {...register("message", { 
    required: "Please enter a message"
  })}
></textarea>
{errors['message'] && <div className="text-red-600">{errors['message'].message}</div>}

3. 修正reCaptcha验证逻辑

移除reCaptchaValue中多余的alert,后端返回的res.data.success已经用来设置valid状态,无需额外弹窗:

const reCaptchaValue = async () => {
  const token = captchaRef.current.getValue();
  console.log(token);
  try {
    const res = await axios.post("http://localhost:4000/status", {
      response: token,
    });
    console.log(res);
    setValid(res.data.success);
  } catch (err) {
    console.log(err);
    setValid(false);
  }
};

4. 清理冗余代码

移除手动维护的formErrors状态和相关的手动字段检查代码,因为react-hook-form已经处理了这些工作:

// 移除以下代码
const [formErrors, setFormErrors] = useState({});
// 以及submitForm中所有手动检查字段和setFormErrors的逻辑

修复后核心逻辑

  • 表单提交时,react-hook-form自动验证所有字段,不符合规则时直接显示对应错误提示
  • 表单验证通过后,才会进入submitForm函数,先检查reCaptcha的valid状态
  • 若reCaptcha未验证,弹出提示;验证通过则提交表单,成功后重置表单与reCaptcha状态

内容的提问来源于stack exchange,提问作者Jeremiah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 15:09:57