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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:16:02