React.js中如何切换按钮状态并在表单提交后显示提示信息?
实现表单提交后的反馈效果
要给你的React表单添加提交反馈,核心是通过状态管理跟踪邮件发送的状态,再根据状态动态更新按钮样式/文字、显示提示信息。以下是具体实现方案:
1. 引入状态变量
首先添加useState来管理发送状态、成功/错误信息:
import React, { useRef, useState } from 'react'; // 新增useState import emailjs from '@emailjs/browser';
在组件内部定义状态:
const MessageMe = props =>{ const form = useRef(); // 新增状态:是否正在发送、是否发送成功、错误信息 const [isSending, setIsSending] = useState(false); const [sendSuccess, setSendSuccess] = useState(false); const [sendError, setSendError] = useState(''); // ... 后续代码 };
2. 完善发送逻辑
修改sendEmail函数,在发送前后更新状态,并添加自动重置状态的逻辑(避免反馈一直显示):
const sendEmail = (e) => { e.preventDefault(); // 发送前重置状态,设置"正在发送" setIsSending(true); setSendSuccess(false); setSendError(''); emailjs.sendForm('servicekey', 'templatekey', form.current, 'publickey') .then((result) => { console.log(result.text); e.target.reset(); // 发送成功:更新状态,3秒后重置成功状态 setSendSuccess(true); setTimeout(() => setSendSuccess(false), 3000); }, (error) => { console.log(error.text); // 发送失败:更新错误信息 setSendError('Failed to send message, please try again later.'); }) .finally(() => { // 无论成功失败,结束"正在发送"状态 setIsSending(false); }); };
3. 实现按钮动画+文字切换
根据状态动态修改按钮的文字、样式和禁用状态:
<button className={`messageme-button ${isSending ? 'sending' : ''} ${sendSuccess ? 'sent' : ''}`} type="submit" disabled={isSending} > {isSending ? 'Sending...' : sendSuccess ? 'Message Sent!' : 'SEND MESSAGE'} </button>
4. 添加自定义提示信息(可选)
在表单下方添加成功/错误提示,可完全自定义样式:
return ( <div className="messageme-container"> <form className="messageme-form" ref={form} onSubmit={sendEmail}> {/* 原有表单输入项... */} <button className={`messageme-button ${isSending ? 'sending' : ''} ${sendSuccess ? 'sent' : ''}`} type="submit" disabled={isSending} > {isSending ? 'Sending...' : sendSuccess ? 'Message Sent!' : 'SEND MESSAGE'} </button> </form> {/* 新增提示信息 */} {sendSuccess && <div className="feedback success">Message sent successfully!</div>} {sendError && <div className="feedback error">{sendError}</div>} </div> );
5. 添加样式(关键动画和自定义样式)
在CSS中添加按钮动画和提示信息样式:
/* 原有按钮基础样式保留,新增以下 */ .messageme-button { /* 基础样式:比如背景色、 padding、border等 */ transition: all 0.3s ease; } /* 发送中状态:显示加载动画 */ .messageme-button.sending { color: transparent; position: relative; cursor: not-allowed; } .messageme-button.sending::after { content: ''; position: absolute; width: 18px; height: 18px; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid #fff; border-top-color: transparent; border-radius: 50%; animation: spin 1s linear infinite; } /* 发送成功状态:改变按钮颜色 */ .messageme-button.sent { background-color: #27ae60; } /* 提示信息样式 */ .feedback { margin-top: 12px; font-size: 14px; padding: 8px 12px; border-radius: 4px; } .feedback.success { background-color: #d4edda; color: #155724; } .feedback.error { background-color: #f8d7da; color: #721c24; } @keyframes spin { to { transform: translate(-50%, -50%) rotate(360deg); } }
完整组件代码
import React, { useRef, useState } from 'react'; import emailjs from '@emailjs/browser'; const MessageMe = props =>{ const form = useRef(); const [isSending, setIsSending] = useState(false); const [sendSuccess, setSendSuccess] = useState(false); const [sendError, setSendError] = useState(''); const sendEmail = (e) => { e.preventDefault(); setIsSending(true); setSendSuccess(false); setSendError(''); emailjs.sendForm('servicekey', 'templatekey', form.current, 'publickey') .then((result) => { console.log(result.text); e.target.reset(); setSendSuccess(true); setTimeout(() => setSendSuccess(false), 3000); }, (error) => { console.log(error.text); setSendError('Failed to send message, please try again later.'); }) .finally(() => { setIsSending(false); }); }; return ( <div className="messageme-container"> <form className="messageme-form" ref={form} onSubmit={sendEmail}> <div className="namebox"> <input className="messageme-input" placeholder="Your Name" type="text" name="user_name" /></div> <div className="mailbox"> <input className="messageme-input" placeholder="Your Email" type="email" name="user_email" /></div> <div className="bodybox"> <textarea className="messageme-body" placeholder="Write me a message!" name="message" /></div> <button className={`messageme-button ${isSending ? 'sending' : ''} ${sendSuccess ? 'sent' : ''}`} type="submit" disabled={isSending} > {isSending ? 'Sending...' : sendSuccess ? 'Message Sent!' : 'SEND MESSAGE'} </button> </form> {sendSuccess && <div className="feedback success">Message sent successfully!</div>} {sendError && <div className="feedback error">{sendError}</div>} </div> ); }; export default MessageMe;
你可以根据自己的需求调整动画效果、颜色、提示文字,或者只保留按钮反馈/提示信息其中一种。
内容的提问来源于stack exchange,提问作者Keith Lavoie
相关产品推荐
相关产品推荐

