1

我使用 Sendgrid 在我的 rails/react 应用程序中添加了一个联系表单。一切正常,但每次通过联系表提交内容时,我都会收到 3-5 封电子邮件。他们中的一些人缺少联系表中的数据。我无法在我的代码中发现这些重复的电子邮件。

前端联系表格:

import React, { useState } from "react";
import { Redirect } from "react-router-dom";
import _ from "lodash";

import ErrorList from "../utilities/ErrorList";

export const ContactForm = () => {
  let defaultFields = {
    name: "",
    email: "",
    subject: "",
    message: "",
  };

  const [message, setMessage] = useState(defaultFields);
  const [errors, setErrors] = useState({});
  const [successMessage, setSuccessMessage] = useState();

  if (successMessage) {
    return <Redirect to="/success" />;
  }

  const newMessage = (formData) => {
    fetch("/api/v1/contact", {
      method: "POST",
      body: JSON.stringify(formData),
      credentials: "same-origin",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
    })
      .then((response) => {
        if (response.ok) {
          return response;
        } else {
          let errorMessage = `${response.status} (${response.statusText})`,
            error = new Error(errorMessage);
          throw error;
        }
      })
      .then((response) => response.json())
      .then((body) => {
        if (body.sent) {
          setSuccessMessage(true);
        } else {
          setSuccessMessage(false);
        }
      })
      .catch((error) => console.error(`Error in fetch: ${error.message}`));
  };

  const handleChange = (event) => {
    setMessage({
      ...message,
      [event.currentTarget.name]: event.currentTarget.value,
    });
  };

  const validForSubmission = () => {
    let submitErrors = {};
    const requiredFields = ["name", "email", "subject", "message"];
    requiredFields.forEach((field) => {
      if (
        message[field].trim() === "" ||
        message[field].trim() === "" ||
        message[field].trim() === "" ||
        message[field].trim() === ""
      ) {
        submitErrors = {
          ...submitErrors,
          [field]: "is blank",
        };
      }
    });
    setErrors(submitErrors);
    return _.isEmpty(submitErrors);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    if (validForSubmission()) {
      newMessage(message);
      newMessage(defaultFields);
    }
  };

  return (
    <section className="section">
      <div className="container">
        <form onSubmit={handleSubmit} className="new-post-form callout">
          <ErrorList errors={errors} />
          <div className="field">
            <label className="label">
              Name:
              <div className="control">
                <input
                  className="input"
                  type="text"
                  placeholder="Please enter your name"
                  name="name"
                  id="name"
                  onChange={handleChange}
                  value={message.name}
                />
              </div>
            </label>
          </div>

          <div className="field">
            <label className="label">
              Email:
              <div className="control">
                <input
                  className="input"
                  type="text"
                  placeholder="Please enter your email address"
                  name="email"
                  id="email"
                  onChange={handleChange}
                  value={message.email}
                />
              </div>
            </label>
          </div>

          <div className="field">
            <label className="label">
              Subject:
              <div className="control">
                <input
                  className="input"
                  type="text"
                  placeholder="Please add a message subject"
                  name="subject"
                  id="subject"
                  onChange={handleChange}
                  value={message.subject}
                />
              </div>
            </label>
          </div>

          <div className="field">
            <label className="label">
              Message:
              <div className="control">
                <textarea
                  className="textarea"
                  placeholder="Add your message here"
                  name="message"
                  id="message"
                  onChange={handleChange}
                  value={message.message}
                ></textarea>
              </div>
            </label>
          </div>

          <div className="field is-grouped">
            <div className="control">
              <button className="button is-link">Submit</button>
            </div>
            <div className="control">
              <button className="button is-link is-light">Cancel</button>
            </div>
          </div>
        </form>
        {successMessage === false && (
          <div className="blog-flex">
            <p>Sorry your message couldn&apos;t be sent. Please try again and make sure all fields are filled out.</p>
          </div>
        )}
      </div>
    </section>
  );
};

export default ContactForm;

从联系表单提交的数据命中contact_controller

require 'pry'

class Api::V1::ContactController < ApiController

  before_action :contact_params, only: [:create]

  def create
    @message = contact_params
    ContactForm.send_message_email(@message).deliver
    
    if ContactForm.send_message_email(@message).deliver
      render json: {sent: true}
    else
      render json: {sent: false}
    end
  end
  
  protected

  def contact_params
    params.require(:contact).permit([:name, :email, :subject, :message])
  end

end

应用程序/邮件中的 ContactForm

require 'pry'

class ContactForm < ApplicationMailer

  default :from => 'info@maddoxgreyauthor.com'

  # send email from contact form
  def send_message_email(message)
    @message = message
    mail( :to => 'info@maddoxgreyauthor.com',
    :subject => 'New Message From Maddox Grey Author' )
  end
end

最后是电子邮件的布局。这是在 app/views/contact_forms/send_message_email.html.erb

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>New message received from <%= @message["name"] %>!</h1>
    <p>Email: <%= @message["email"] %></p>
    <p>Subject: <%= @message["subject"] %></p>
    <p>Message: <%= @message["message"] %></p>
  </body>
</html>
4

1 回答 1

2

在这里,您发送了两次电子邮件:

  def create
    @message = contact_params
    ContactForm.send_message_email(@message).deliver #<--- once
    
    if ContactForm.send_message_email(@message).deliver #<--- twice
      render json: {sent: true}
    else
      render json: {sent: false}
    end
  end

执行以下操作至少应该有助于处理其中一封重复的电子邮件:

  def create
    @message = contact_params
    send_email = ContactForm.send_message_email(@message).deliver 
    
    if send_email 
      render json: {sent: true}
    else
      render json: {sent: false}
    end
  end

或者更节省空间的解决方案:

  def create
      render json: {sent: !!ContactForm.send_message_email(contact_params).deliver}
  end

其次,在这里您还要调用 API 函数两次:

  const handleSubmit = (event) => {
    event.preventDefault();
    if (validForSubmission()) {
      newMessage(message); //<-- Once
      newMessage(defaultFields); //<-- Twice
    }
  };
于 2021-07-14T19:51:01.897 回答