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
相关产品推荐
相关产品推荐

