在自定义React组件中使用EmailJS:邮件内容缺失问题求助
问题排查与修复方案
核心问题分析
邮件能发送但丢失用户输入内容,主要是EmailJS模板变量与表单字段不匹配、API调用逻辑错误、表单控件参数错误这几个原因导致的:
1. EmailJS模板变量与表单name不对应
EmailJS通过表单字段的name属性匹配模板中的变量。你的代码里输入框name是mail和body,但如果EmailJS模板里用的是其他变量名(比如{{user_email}}、{{user_message}}),就会导致内容无法填充。
修复:
- 要么把EmailJS模板里的变量改成和表单
name一致:{{mail}}、{{body}} - 要么把表单输入框的
name改成和模板变量一致,比如:<Input name="user_email" // 对应模板里的{{user_email}} // ...其他属性 /> <Input name="user_message" // 对应模板里的{{user_message}} // ...其他属性 />
2. sendForm的回调逻辑错误
你现在的.then(alert("Message Sent!"))会直接执行alert,不是在请求成功后执行,而且没有处理失败情况,也没更新发送状态。
修复:
const sendEmail = (e) => { e.preventDefault(); setSending(true); emailjs.sendForm('ID', 'KEY', form.current, 'SECRET') .then(() => { alert("Message Sent! I'll reply you ASAP!"); setComplete(true); }) .catch(err => console.error('发送失败:', err)) .finally(() => { setSending(false); e.target.reset(); }); };
3. 消息输入框的type参数错误
消息框设置了type="email",这会限制输入内容必须符合邮箱格式,导致用户输入的普通消息可能被过滤或无法正确提交。
修复:
把消息输入框的type改成text,或者因为是多行输入,直接去掉type属性(如果你的Input组件默认支持多行文本):
<Input name="body" required multiline // ...其他属性 type="text" // 替换原来的type="email" {...message} />
4. 状态更新缺失
你定义了sending和complete状态,但没有在发送流程中正确更新,导致按钮的加载状态不生效,页面也不会切换到完成状态。上面的sendEmail修改已经包含了状态更新的逻辑,确保按钮能显示加载状态,发送完成后切换到完成视图。
修改后的完整代码示例
export const Contact = () => { const email = useFormInput(''); const message = useFormInput(''); const [sending, setSending] = useState(false); const [complete, setComplete] = useState(false); const initDelay = tokens.base.durationS; const form = useRef() const sendEmail = (e) => { e.preventDefault(); setSending(true); emailjs.sendForm('ID', 'KEY', form.current, 'SECRET') .then(() => { alert("Message Sent! I'll reply you ASAP!"); setComplete(true); }) .catch(err => console.error('发送失败:', err)) .finally(() => { setSending(false); e.target.reset(); }); } return ( <Section className={styles.contact}> <Meta title="Contact" description="Send me a message if you're interested in discussing a project or if you just want to say hi" /> <Transition unmount in={!complete} timeout={1600}> {(visible, status) => ( <form ref={form} onSubmit={sendEmail} className={styles.form}> <Heading className={styles.title} data-status={status} level={3} as="h1" style={getDelay(tokens.base.durationXS, initDelay, 0.3)} > <DecoderText text="Keep in Touch!" start={status !== 'exited'} delay={300} /> </Heading> <Divider className={styles.divider} data-status={status} style={getDelay(tokens.base.durationXS, initDelay, 0.4)} /> <Input name="mail" // 确保和EmailJS模板变量一致 required className={styles.input} data-status={status} style={getDelay(tokens.base.durationXS, initDelay)} autoComplete="email" label="Your Email" type="email" maxLength={512} {...email} /> <Input name="body" // 确保和EmailJS模板变量一致 required multiline className={styles.input} data-status={status} style={getDelay(tokens.base.durationS, initDelay)} autoComplete="off" label="Message" type="text" // 修正type属性 maxLength={4096} {...message} /> <Button className={styles.button} data-status={status} data-sending={sending} style={getDelay(tokens.base.durationM, initDelay)} disabled={sending} loading={sending} loadingText="Sending..." icon="send" type="submit" > Send message </Button> </form> )} </Transition> <Footer className={styles.footer} /> </Section> ); };
内容的提问来源于stack exchange,提问作者javiLPot
相关产品推荐
相关产品推荐

