如何在Next.js+TypeScript中从Axios响应设置表单错误信息?
解决Next.js注册表单服务器端错误信息展示问题
核心错误原因
你的代码存在两个关键问题:
- useState顺序完全写反:React的
useState返回值是[状态变量, 更新函数],你把更新函数和状态变量的位置搞反了,导致调用setEmailError时实际是在调用字符串/空值,触发TS2349错误。 - 服务器返回错误为数组格式:后端返回的
errors.email和errors.password是字符串数组(比如["The email has already been taken."]),直接赋值会导致状态类型不匹配。
修正后的完整代码
const RegisterPage: NextPageWithLayout = () => { const [isSubmitting, setIsSubmitting] = useState<boolean>(false); // 修正useState顺序:[状态变量, 更新函数] const [emailError, setEmailError] = useState<string | null>(null); const [passwordError, setPasswordError] = useState<string | null>(null); // 定义错误响应类型,替代@ts-ignore interface ValidationErrorResponse { message: string; errors: { email?: string[]; password?: string[]; }; } const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); if (isSubmitting) return; setIsSubmitting(true); // 重置之前的错误信息 setEmailError(null); setPasswordError(null); try { // 替换为你的实际API调用逻辑 // const response = await fetch('/api/register', { // method: 'POST', // body: new FormData(e.currentTarget), // }); // if (!response.ok) { // const errorData = await response.json() as ValidationErrorResponse; // throw errorData; // } // 处理注册成功逻辑 } catch (err) { const errorData = err as ValidationErrorResponse; const errors = errorData?.errors; if (errors) { // 取数组第一个错误信息,适配后端返回结构 setEmailError(errors.email?.[0] || null); setPasswordError(errors.password?.[0] || null); } } finally { setIsSubmitting(false); } }; // 表单渲染示例 return ( <form onSubmit={handleSubmit}> <div> <label>邮箱</label> <input type="email" name="email" /> {emailError && <p className="text-red-500">{emailError}</p>} </div> <div> <label>密码</label> <input type="password" name="password" /> {passwordError && <p className="text-red-500">{passwordError}</p>} </div> <button type="submit" disabled={isSubmitting}>注册</button> </form> ); };
关键修正点说明
- 修正useState顺序:将
[setEmailError, emailError]调整为[emailError, setEmailError],彻底解决TS2349调用错误。 - 适配数组错误信息:用
errors.email?.[0]提取数组第一个错误内容,结合可选链操作符避免空值报错。 - 添加类型定义:创建
ValidationErrorResponse接口,替代不安全的@ts-ignore,提升类型安全性。 - 重置错误状态:提交表单时清空旧错误,避免残留信息干扰用户。
- finally块管理加载状态:确保请求结束后无论成败,都能恢复按钮可用状态。
内容的提问来源于stack exchange,提问作者Connor Leech
相关产品推荐
相关产品推荐

