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

如何修复基于EmailJS的无后端React联系表单问题

问题:EmailJS表单提交时页面刷新且无法收到邮件

我正在给作品集网站添加邮件联系表单,使用EmailJS实现无后端方案。已经在代码中加入e.preventDefault()语句,但提交表单时页面仍会刷新并跳转回主页,多次测试均未收到邮件,且控制台无任何错误提示。

相关代码位于GitHub仓库的Contact组件中,核心代码如下:

处理表单提交的Hooks代码

// handle form submission and loading state
const [formSent, setFormSent] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const form = useRef();

const handleSubmit = e => {
    e.preventDefault();
    const req = {
        from_name: name,
        from_email: email,
        message: message
    }
    setIsLoading(true);
    sendEmail(req);
}

const sendEmail = req => {
    const params = req;
    window.emailjs.send('portfolio_contact', 'template_suo050u', params, 'BfYQUzIt-ih1oyqmY')
        .then(res => {
            setIsLoading(false);
            setFormSent(true);
            console.log(res);
        }).catch(e => {
            setIsLoading(false);
        });
}

表单JSX代码

<Col>
    {isLoading ?
        <Spinner animation='border' variant='info'/>
        : formSent ? (
            <div className='d-flex justify-content-center'>
                <p className='success-text'> Your message has been sent! </p>
            </div>
        )
        : <></>
    }
    <Form>
        <Form.Group id='contact-form' ref={form} onSubmit={handleSubmit} className='my-3'>
            {/* name input */}
            <div className='d-flex justify-content-center'>
                <Form.Control type='text' placeholder='Name' name='name' autoComplete='name' defaultValue={name} onBlur={handleChange} style={{ width: '65%' }} />
            </div>
            {/* email input */}
            <div className='my-3 d-flex justify-content-center'>
                <Form.Control type='email' placeholder='Email' name='email' autoComplete='email' defaultValue={email} onBlur={handleChange} style={{ width: '65%' }} />
            </div>
            {/* message text area */}
            <div className='my-3 d-flex justify-content-center'>
                <Form.Control as='textarea' placeholder='Tell me about your project' name='message' rows={5} defaultValue={message} onBlur={handleChange} style={{ width: '65%' }} />
            </div>
            {/* if errorMessage print errorMessage text to alert user */}
            {errorMessage && (
                <div className='my-3 d-flex justify-content-center'>
                    <p className='error-text'>{errorMessage}</p>
                </div>
            )}
            <div className='my-3 d-flex justify-content-center'>
                <Button type='submit' className='btn'>Send</Button>
            </div>
        </Form.Group>
    </Form>
</Col>

问题诊断与修复方案

1. 页面刷新的核心原因

你把onSubmit绑定在了Form.Group组件上,但Bootstrap React中,表单的默认提交行为是由根<Form>元素触发的,你的e.preventDefault()根本没生效——因为触发提交事件的不是绑定了处理函数的Form.Group,而是外层的Form。

修复步骤:
将onSubmit={handleSubmit}从<Form.Group>移到外层<Form>上:

<Form onSubmit={handleSubmit}>
    <Form.Group id='contact-form' ref={form} className='my-3'>
        {/* 原有表单内容保持不变 */}
    </Form.Group>
</Form>

2. 无法收到邮件的排查方向

(1)EmailJS参数验证

核对window.emailjs.send的四个参数是否完全匹配EmailJS后台配置:

  • 服务ID(portfolio_contact):确认服务已启用
  • 模板ID(template_suo050u):检查模板内的变量名和你传入的from_name、from_email、message完全一致(注意大小写)
  • 用户ID(BfYQUzIt-ih1oyqmY):核对账户的公共API密钥

(2)表单数据获取问题

当前用defaultValue和onBlur更新状态,若用户直接回车提交而未触发onBlur,name、email、message可能还是初始空值。建议改用onChange实时更新,确保提交时数据有效:

<Form.Control 
    type='text' 
    placeholder='Name' 
    name='name' 
    autoComplete='name' 
    value={name} 
    onChange={handleChange} 
    style={{ width: '65%' }} 
/>

(所有输入框都替换成value绑定+onChange触发)

(3)错误日志缺失

当前catch块仅重置加载状态,未记录错误信息,导致无法定位EmailJS的返回错误。添加日志便于排查:

.catch(e => {
    setIsLoading(false);
    console.error('邮件发送失败:', e);
});

3. 额外优化建议

  • 给表单添加必填字段验证,避免空提交
  • 提交成功后重置表单状态,方便用户再次提交

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:45:22