React DatePicker+EmailJS发送邮件时时间显示不一致问题排查
问题:React DatePicker时间在EmailJS邮件中显示与控制台不一致
我开发了一个预约表单,使用React DatePicker选择预约时间,通过EmailJS将预约信息发送到邮箱。目前已能通过EmailJS接收数据,但发现邮件中的时间与控制台打印的时间不一致——控制台显示的时间与用户选择的一致,邮件里的时间却存在偏差。
相关代码如下:
import { React, useRef } from "react"; import { useForm, Controller } from "react-hook-form"; import emailjs from "@emailjs/browser"; import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; const Contact = () => { const form = useRef(); const time = useRef(); const { control } = useForm(); const sendEmail = (e) => { const info = { name: form.current["name"].value, email: form.current["email"].value, phone: form.current["phone"].value, message: form.current["message"].value, size: form.current["size"].value, time: time.current.props.selected, }; console.log("log name", form.current["name"].value); console.log("log email", form.current["email"].value); console.log("log phone", form.current["phone"].value); console.log("log message", form.current["message"].value); console.log("log size", form.current["size"].value); console.log("log time", time.current.props.selected); e.preventDefault(); emailjs .send("serviceID", "templateID", info, "publicKey") .then( (result) => { console.log(result.status, result.text); }, (error) => { console.log(error.status, error.text); } ); }; return ( <section class="page-section" id="contact"> <div class="container"> <div class="text-center"> <h2 class="section-heading text-uppercase">Reservation</h2> </div> <form id="contactForm" ref={form} onSubmit={sendEmail}> <div class="row align-items-stretch mb-5"> <div class="col-md-6"> <div class="form-group"> <Controller control={control} name="time" id="time" render={({ field }) => ( <DatePicker placeholderText="Select date" onChange={(date) => field.onChange(date)} selected={field.value} showTimeSelect dateFormat="Pp" timeFormat="p" minDate={new Date()} minTime={new Date().setHours(17, 0, 0, 0)} maxTime={new Date().setHours(21, 0, 0, 0)} ref={time} /> )} /> </div>
附加说明:网站界面、控制台日志及收到的邮件截图显示,控制台打印的时间与用户选择的一致,但邮件中的时间存在时区偏移或格式转换错误类的偏差。
解答
问题原因
- Date对象序列化的时区问题:你传递给EmailJS的
time是原生Date对象,EmailJS处理时会将其序列化为UTC时区的ISO格式字符串,而控制台打印Date对象时,浏览器会自动转换为本地时区显示,因此出现偏差。 - 通过ref获取props的不可靠性:依赖
time.current.props.selected获取时间的方式,受React DatePicker内部实现影响,可能无法稳定获取最新的本地时间对象,进一步增加出错概率。
解决方案
方案1:将Date对象格式化为指定字符串后发送
直接把Date对象转换为和控制台显示一致的格式,避免时区问题。可以复用DatePicker的dateFormat配置:
// 提取dateFormat为常量,方便复用 const DATE_FORMAT = "Pp"; // 引入date-fns(React DatePicker依赖该库,无需额外安装) import { format } from 'date-fns'; const sendEmail = (e) => { const info = { // ...其他字段 time: time.current.props.selected ? format(time.current.props.selected, DATE_FORMAT) : '', }; // ...后续代码 };
也可以手动指定格式化规则:
const info = { // ...其他字段 time: time.current.props.selected ? time.current.props.selected.toLocaleString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: true }) : '', };
方案2:改用react-hook-form的表单值获取时间
既然用了Controller包裹DatePicker,直接从react-hook-form的表单值中获取时间更可靠,无需额外ref:
// 解构添加getValues const { control, getValues } = useForm(); const sendEmail = (e) => { const selectedTime = getValues('time'); const info = { // ...其他字段 time: selectedTime ? format(selectedTime, "Pp") : '', }; // ...后续代码 };
内容的提问来源于stack exchange,提问作者Hyunsu Kim
相关产品推荐
相关产品推荐

