You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js+TypeScript中从Axios响应设置表单错误信息?

解决Next.js注册表单服务器端错误信息展示问题

核心错误原因

你的代码存在两个关键问题:

  1. useState顺序完全写反:React的useState返回值是[状态变量, 更新函数],你把更新函数和状态变量的位置搞反了,导致调用setEmailError时实际是在调用字符串/空值,触发TS2349错误。
  2. 服务器返回错误为数组格式:后端返回的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 19:20:45