我想通过 Nodemailer、TypeScript 和 NextJS 发送电子邮件。状态组件的 contact.tsx 文件中存在错误。如何修复错误?使用 setform 会导致表单状态错误。我是打字稿的初学者,找不到任何解决方案。如果有人能解决这个问题,我将不胜感激。
contact.tsx
用于页面的文件。
import React, { useState } from 'react';
export default function Contact() {
const [inputs, setInputs] = useState({
fname: '',
lname: '',
email: '',
message: ''
});
const [form, setForm] = useState('')
const handleChange = (e) => {
setInputs((prev) => ({
...prev,
[e.target.id]: e.target.value,
}))
}
const onSubmitForm = async (e) => {
e.preventDefault()
if (inputs.fname && inputs.email && inputs.phone && inputs.message) {
setForm({ state: 'loading' })
try {
const res = await fetch(`api/contact`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(inputs),
})
const { error } = await res.json()
if (error) {
setForm({
state: 'error',
message: error,
})
return
}
setForm({
state: 'success',
message: 'Your message was sent successfully.',
})
setInputs({
fname: '',
lname: '',
email: '',
message: '',
})
} catch (error) {
setForm({
state: 'error',
message: 'Something went wrong',
})
}
}
}
return (
<form onSubmit={(e) => onSubmitForm(e)}>
<input
type="text"
id="fname"
value={inputs.fname}
onChange={handleChange}
className="form-control"
placeholder="First Name"
required
/>
<input
type="text"
id="lname"
value={inputs.fname}
onChange={handleChange}
className="form-control"
placeholder="Last Name"
required
/>
<input
type="email"
id="email"
value={inputs.email}
onChange={handleChange}
className="form-control"
placeholder="Email"
required
/>
<textarea
id="message"
value={inputs.message}
onChange={handleChange}
rows={4}
className="form-control"
placeholder="Messages"
required
></textarea>
<button
type="submit"
className="button"
>
Send inquiry
</button>
{form.state === 'loading' ? (
<div>Sending....</div>
) : form.state === 'error' ? (
<div>{form.message}</div>
) : (
form.state === 'success' && <div>Sent successfully</div>
)}
</form>
);
}
我发现了一些可能是您问题的根源。
'useState' 钩子中'setForm' 的第一个问题,您已经使用空字符串 ('') 作为初始状态初始化了 'form'。但是,在代码的后面,您尝试使用包含状态和消息属性的对象使用 setForm 来更新表单。这可能会导致类型错误,因为 form 应该是一个字符串,但您正试图将其设置为一个对象。
您可以使用包含“状态”和“消息”属性的对象初始化“表单”来修复此问题:
const [form, setForm] = useState({ state: '', message: '' });
我发现的第二个问题是“handleChange”:在“handleChange”函数中,您使用 prev 作为回调函数的参数,这意味着 prev 是类型
React.SetStateAction<{ fname: string; lname: string; email: string; message: string; }>.
但是,您在访问 e.target.id 和 e.target.value 时未指定它们的类型,这可能会导致类型错误。
您可以通过为事件对象“e”和回调函数中的“prev”参数提供类型注释来解决此问题,如下所示:
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { id, value } = e.target;
setInputs((prev: React.SetStateAction<typeof inputs>) => ({
...prev,
[id]: value,
}));
};
这应该可以解决。确保您的 API 端点
/api/contact
在您的服务器上正确配置以处理发布请求并返回预期的响应。
if (inputs.fname && inputs.email && inputs.message) {
setForm({ state: 'loading' });
try {
const res = await fetch(`api/contact`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(inputs),
});
// Rest of the code for handling response and setting state
} catch (error) {
setForm({
state: 'error',
message: 'Something went wrong',
});
}
}