React表单验证后通过Email.js发送邮件异常问题求助
问题:React表单验证未通过时仍触发Email.js邮件发送
问题原因
React的setState是异步操作,在handleSubmit中调用setFormErrors(validate(formValues))后,formErrors的状态不会立即更新。此时紧接着执行Object.keys(formErrors).length === 0判断,使用的还是更新前的旧状态,导致即使验证出错,判断也可能返回true,进而触发邮件发送。
解决方案
方案1:同步获取验证结果后直接判断
先调用验证函数得到错误信息,保存到变量中,再用这个变量判断是否发送邮件,同时更新formErrors状态。
修改后的handleSubmit函数:
const handleSubmit = (e) => { e.preventDefault(); // 先同步获取验证错误信息 const validationErrors = validate(formValues); setFormErrors(validationErrors); setIsSubmit(true); // 直接使用刚获取的验证结果判断 if (Object.keys(validationErrors).length === 0) { emailjs .sendForm( "", "", form.current, "" ) .then( (result) => { console.log(result.text); }, (error) => { console.log(error.text); } ); } };
方案2:使用useEffect监听状态变化
通过useEffect监听formErrors和isSubmit的状态变化,当提交触发且验证无错误时,再执行邮件发送逻辑。
添加useEffect并修改handleSubmit:
import React, { useState, useRef, useEffect } from "react"; // 引入useEffect // ... 其他代码保持不变 useEffect(() => { // 当提交状态为true且无验证错误时发送邮件 if (isSubmit && Object.keys(formErrors).length === 0) { emailjs .sendForm( "", "", form.current, "" ) .then( (result) => { console.log(result.text); // 可选:发送成功后重置表单和提交状态 setFormValues(initialValues); setIsSubmit(false); }, (error) => { console.log(error.text); setIsSubmit(false); } ); } }, [formErrors, isSubmit]); // 依赖项:formErrors和isSubmit const handleSubmit = (e) => { e.preventDefault(); setFormErrors(validate(formValues)); setIsSubmit(true); };
说明
- 方案1更直接,通过同步获取验证结果避免异步状态更新的延迟问题;
- 方案2利用React的状态监听机制,确保在
formErrors完全更新后再执行后续逻辑,适合需要在状态变化后做后续处理的场景。
内容的提问来源于stack exchange,提问作者Igor Jevremovic
相关产品推荐
相关产品推荐

