如何通过电子邮件JS发送表单数据?

How to send form data via emailJS?

提问人:Christoper Chamberlain 提问时间:7/18/2023 更新时间:7/18/2023 访问量:114

问:

我有一个多页的 React 表单,我想通过电子邮件将表单数据发送到我的电子邮件。目前,当我提交表单时,我只收到一个空的电子邮件模板。似乎我的 Form 组件无法访问其他组件中的数据。如何从我的表单组件访问其他组件中的表单数据?

表单组件

import styled from "styled-components"
import { useState, useRef } from "react";
import Welcome from './Welcome';
import PersonalInfo from './PersonalInfo';
import BackgroundInfo from './BackgroundInfo';
import BusinessDescription from './BusinessDescription';
import ServicesDescription from './ServicesDescription';
import WebsiteGoals from './WebsiteGoals';
import ContentType from './ContentType';
import WebsiteFeatures from './WebsiteFeatures';
import UniqueQualities from './UniqueQualities';
import TargetDemographic from './TargetDemographic'
import BrandPersonality from './BrandPersonality';
import DesignPreferences from './DesignPreferences';
import FavoriteWebsites from './FavoriteWebsites';
import Submit from './Submit';
import emailjs from '@emailjs/browser';
import ConfettiExplosion from 'react-confetti-explosion';

function Form() {
  const [page, setPage] = useState(0);
  const [isExploding, setIsExploding] = useState(false);
  const FormTitles = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
  const form = useRef();
  const confettiProps = {
    force: 0.9,
    duration: 4000,
    particleCount: 500,
    width: 2000, 
    height: '200vh', 
  }

  const sendEmail = (e) => {
    e.preventDefault();

    emailjs.sendForm(
      import.meta.env.VITE_EMAILJS_SERVICE_ID, 
      import.meta.env.VITE_EMAILJS_TEMPLATE_ID, 
      form.current, 
      import.meta.env.VITE_EMAILJS_PUBLIC_KEY)
      .then((result) => {
          console.log(result.text);
          console.log('message sent');
      }, (error) => {
          console.log(error.text);
      });
  };

  const handleIncrementClick = (e) => {
    setPage((currPage) => currPage + 1)
  }

  const handleDecrementClick = (e) => {
    setPage((currPage) => currPage - 1)
  }

  console.log(<PersonalInfo/>)

  **const pageDisplay = () => {**
    switch(page) {
      case 0:
       return <Welcome/>;
       break;
      case 1:
        return <PersonalInfo/>;
        break;
      case 2:
        return <BackgroundInfo/>;
        break;
      case 3:
        return <BusinessDescription/>;
        break;
      case 4:
        return <ServicesDescription/>;
        break;
      case 5:
        return <WebsiteGoals/>;
        break;
      case 6:
        return <ContentType/>;
        break;
      case 7:
        return <WebsiteFeatures/>;
        break;
      case 8:
        return <UniqueQualities/>;
        break;
      case 9:
        return <TargetDemographic/>;
        break;
      case 10:
        return <BrandPersonality/>;
        break;
      case 11:
        return <DesignPreferences/>;
        break;
      case 12:
        return <FavoriteWebsites/>;
        break;
      case 13:
        return <Submit/>;
        break;
    }
  }
  
  return (
    <FormWrapperOuter ref={form} onSubmit={sendEmail}>
        <ProgressBarContainer>
          <ProgressBar style={{width: `${page * 8}%`}}></ProgressBar>
        </ProgressBarContainer>
        <FormWrapperInner>
        **<Body>{pageDisplay()}</Body>**
        <ButtonContainer>
            { page > 0 && <PrevButton disabled={page === 0} type="button" onClick={handleDecrementClick}><i className="fa-solid fa-arrow-left-long"></i></PrevButton>}
            {page < FormTitles.length - 1 && <NextButton  disabled={page === FormTitles.length - 1} type="button" onClick={handleIncrementClick}>{page > 0 ? <p>Next</p> : <p>Let's go!</p>}<i className="fa-solid fa-arrow-right-long"></i></NextButton>}
            <SubmitBtn type="submit" onClick={() => setIsExploding(!isExploding)}><p>Submit</p><i class="fa-solid fa-paper-plane"></i></SubmitBtn>
            {isExploding && <ConfettiExplosion {...confettiProps}/>}
        </ButtonContainer>
        </FormWrapperInner>
    </FormWrapperOuter>
  )
}

我想从中获取数据的一个组件。

import React from 'react'
import styled from 'styled-components'
import { useState, useEffect } from 'react';

function PersonalInfo() {
const [firstAndLastName, setfirstAndLastName] = useState(JSON.parse(sessionStorage.getItem('FirstAndLastName' ?? '')));

const [email, setEmail] = useState(JSON.parse(sessionStorage.getItem('email' ?? '')));

const [companyName, setCompanyName] = useState(JSON.parse(sessionStorage.getItem('companyName' ?? '')));

const [companyIndustry, setCompanyIndustry] = useState(JSON.parse(sessionStorage.getItem('companyIndustry' ?? '')));

const handleNameChange = (e) => {
  sessionStorage.setItem('FirstAndLastName', JSON.stringify(e.target.value));
  setfirstAndLastName(e.target.value)
}

const handleEmailChange = (e) => {
  sessionStorage.setItem('email', JSON.stringify(e.target.value));
  setEmail(e.target.value)
}

const handleCompanyNameChange = (e) => {
  sessionStorage.setItem('companyName', JSON.stringify(e.target.value));
  setCompanyName(e.target.value)
}

const handleCompanyIndustryChange = (e) => {
  sessionStorage.setItem('companyIndustry', JSON.stringify(e.target.value));
  setCompanyIndustry(e.target.value)
}


  return (
    <PersonalInfoContainer>
      <InputContainer>
        <Input 
        name="user_name" 
        type='text' 
        value={firstAndLastName} 
        onChange={handleNameChange} 
        placeholder=''/>
        <Label>First and Last Name</Label>
      </InputContainer>
      <InputContainer>
        <Input  
        name='user_email' 
        type='email' 
        value={email} 
        onChange={handleEmailChange} 
        placeholder=''/>
        <Label>Email</Label>
      </InputContainer>
      <InputContainer>
        <Input 
        name='user_companyName' 
        type='text' 
        value={companyName} 
        onChange={handleCompanyNameChange} 
        placeholder=''/>
        <Label>Company Name</Label>
      </InputContainer>
      <InputContainer>
        <Input 
        name='user_companyIndustry' 
        type='text' 
        value={companyIndustry} 
        onChange={handleCompanyIndustryChange} 
        placeholder=''/>
        <Label>Company Industry</Label>
      </InputContainer>
    </PersonalInfoContainer>
  )
}
reactjs 表单 电子邮件 SMTP

评论


答:

0赞 Tran Loc 7/18/2023 #1

我强烈建议你使用 React-hook-form apis。react-hook-form 库是一个很棒的库,可以处理表单。我制作了一个简单的片段代码,您可以按照它进行操作:

import { Box, Button, Heading, Input } from "@chakra-ui/react";
import { useState } from "react";
import { FormProvider, useForm, useFormContext } from "react-hook-form";

function Step1Component({ isVisible }: { isVisible: boolean }) {
  const { register } = useFormContext();

  /**
   * The idea is to hide the component from naked eye without unmounting it
   */
  return <Box h={isVisible ? "auto" : "0px !important"}>
    <Heading>Name</Heading>
    {/* the register method register the input with react-hook-form, you can also add validation rules here
    for ex: required, minLength, maxLength, pattern, etc */}
    <Input {...register("name")} />
  </Box>
}

function Step2Component({ isVisible }: { isVisible: boolean }) {
  const { register } = useFormContext();

  return <Box h={isVisible ? "auto" : "0px !important"}>
    <Heading>BackgroundInfo</Heading>
    <Input {...register("backgroundInfo")} />
  </Box>
}

export default function MyForm() {
  /**
   * You can access several react-hook-from apis from methods
   * for ex: methods.getValues
   */
  const methods = useForm();
  const [step, setStep] = useState(1);

  /**
   * Now when submit is called, you can access the form data
   * And you can also access the form data with methods.getValues() from anywhere in MyForm component
   * @param data 
   */
  function onSubmit(data: any) {

  }

  /**
   * FormProvider is a react context provider, it provides the react-hook-form methods to all its children
   * So that you can access the methods from anywhere in the children
   */
  return <FormProvider {...methods}>
    <form
      onSubmit={methods.handleSubmit(onSubmit)}>
      <Step1Component isVisible={step === 1} />
      <Step2Component isVisible={step === 2} />
      {/* form navigation logic here */}
      <Button type="submit">Submit</Button>
    </form>
  </FormProvider >
}