NextJS+TypeScript下Nodemailer组件contact.tsx状态错误修复求助
NextJS + TypeScript 联系表单组件修复方案
核心问题梳理
- form状态类型不匹配:初始值为字符串
'',后续赋值为对象,违反TypeScript类型约束 - lname输入框value绑定错误:错误绑定到
inputs.fname,导致输入 lastName 时显示 firstName 的值 - 提交校验引用不存在字段:判断条件中
inputs.phone未定义,组件内无对应输入框,导致校验逻辑失效
修复后的完整代码
import React, { useState } from 'react'; // 定义表单状态的类型 type FormState = { state: 'idle' | 'loading' | 'error' | 'success'; message?: string; }; // 定义输入字段的类型 type Inputs = { fname: string; lname: string; email: string; message: string; }; export default function Contact() { const [inputs, setInputs] = useState<Inputs>({ fname: '', lname: '', email: '', message: '' }); // 初始化form状态为idle,符合类型定义 const [form, setForm] = useState<FormState>({ state: 'idle' }); // 给事件参数添加明确类型 const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { setInputs((prev) => ({ ...prev, [e.target.id]: e.target.value, })); }; const onSubmitForm = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); // 移除不存在的phone校验,保留现有字段的校验 if (inputs.fname && inputs.lname && 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), }); 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={onSubmitForm}> <input type="text" id="fname" value={inputs.fname} onChange={handleChange} className="form-control" placeholder="First Name" required /> <input type="text" id="lname" value={inputs.lname} {/* 修复value绑定错误 */} 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状态展示对应提示 */} {form.state === 'loading' && <div>Sending....</div>} {form.state === 'error' && <div>{form.message}</div>} {form.state === 'success' && <div>Sent successfully</div>} </form> ); }
修复细节说明
类型定义规范
- 新增
FormState和Inputs类型,明确状态结构和输入字段类型,解决TypeScript类型不匹配问题 - 给
useState显式指定类型,提升代码可读性和类型安全性
- 新增
修复输入框绑定错误
- 将lname输入框的
value属性从inputs.fname改为inputs.lname,确保输入值与状态同步
- 将lname输入框的
修正提交校验逻辑
- 移除判断条件中的
inputs.phone,因为组件内未添加该输入框,避免校验逻辑错误
- 移除判断条件中的
完善事件参数类型
- 给
handleChange和onSubmitForm的事件参数添加TypeScript类型,符合React事件类型规范
- 给
内容的提问来源于stack exchange,提问作者Sayan Dey
相关产品推荐
相关产品推荐

