发布于 2026-01-06 5 阅读
0

使用 TypeScript 和 React Hook 表单结合 Zod 进行操作

使用 TypeScript 和 React Hook 表单结合 Zod 进行操作

您好,如果您的应用程序使用了某种 API,那么在发送任何请求之前都必须进行验证!例如,假设您有一个简单的注册页面,其中包含电子邮件和密码字段。假设用户在电子邮件字段中输入了“HelloWorld”,这显然不是一个电子邮件地址。即使我们的 API 会抛出一个错误提示“电子邮件字段应该是电子邮件地址”,但请求发出并返回一个明显会抛出错误的响应所花费的时间并不值得。在我看来,验证应该在前端和后端双向进行。那么我们应该怎么做呢?首先,我们需要安装 Zod 和 React Hook 表单!

npm install react-hook-form zod @hookform/resolvers

安装完成后,我们来为表单创建架构。

import { z } from 'zod';

const SignUpSchema = z.object({
  email: z.string().email(),
  password: z
    .string()
    .min(3)
    .max(20)
});

type SignUpSchemaType = z.infer<typeof SignUpSchema>;
Enter fullscreen mode Exit fullscreen mode

所以现在在我们的模式中,我们规定电子邮件地址必须是字符串类型,密码也必须是字符串类型,长度最少 3 个字符,最多 20 个字符。

现在我们进入表单组件,创建一个简单的表单。

export default function App() {
  return (
    <form  className="form">
      <input className="input" placeholder="email" />
      <input
        className="input"
        placeholder="password"
      />
      <button type="submit">submit!</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

现在我们只需添加 react-hook-form 中的 useForm hook 即可

import { useForm } from "react-hook-form";
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm<SignUpSchemaType>({ resolver: zodResolver(SignUpSchema) });
Enter fullscreen mode Exit fullscreen mode

该钩子将接收一个对象,该对象将来自 (@hookform/resolvers),即 zodResolver!

现在我们准备将输入连接到寄存器旁边的钩子上!

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm<SignUpSchemaType>({ resolver: zodResolver(SignUpSchema) });



  return (
    <form className="form">
      <input className="input" placeholder="email" {...register("email")} />


      <input
        className="input"
        placeholder="password"
        {...register("password")}
      />


      <button type="submit">submit!</button>
    </form>
  );
}

Enter fullscreen mode Exit fullscreen mode

现在,每当我们向这两个字段输入内容时,useForm 就会触发!

现在我们希望在每个输入框下方显示错误信息,以便在出现错误时显示错误提示,例如,如果我们在电子邮件字段中输入“HelloWorld”。

以下是我们通过表单报告错误的方式!

 return (
    <form className="form">
      <input className="input" placeholder="email" {...register("email")} />
      {errors.email && <span>{errors.email.message}</span>}

      <input
        className="input"
        placeholder="password"
        {...register("password")}
      />

      {errors.password && <span>{errors.password.message}</span>}

      <button type="submit">submit!</button>
    </form>
  );
Enter fullscreen mode Exit fullscreen mode

现在,当密码或电子邮件字段出错时,将显示 span 符号。

错误

现在我们需要处理点击提交按钮的情况。

所以首先我们创建一个简单的函数,只有当所有验证都成功时才会触发!

//we should here call like API or something...
  const onSubmit: SubmitHandler<SignUpSchemaType> = (data) => console.log(data);
Enter fullscreen mode Exit fullscreen mode

现在我们为表单添加一个简单的 onSubmit 事件,并像这样从 useForm hook 中调用 handleSubmit 事件。

    <form onSubmit={handleSubmit(onSubmit)} className="form">

Enter fullscreen mode Exit fullscreen mode

现在我们已经完成了验证,然后再将其发送到某个 API。

错误

以下是完整代码

import "./styles.css";
import { z } from "zod";
import { useForm, SubmitHandler } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

const SignUpSchema = z.object({
  email: z.string().email(),
  password: z.string().min(3).max(20)
});
type SignUpSchemaType = z.infer<typeof SignUpSchema>;

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm<SignUpSchemaType>({ resolver: zodResolver(SignUpSchema) });

  //we should here call like API or something...
  const onSubmit: SubmitHandler<SignUpSchemaType> = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="form">
      <input className="input" placeholder="email" {...register("email")} />
      {errors.email && <span>{errors.email.message}</span>}

      <input
        className="input"
        placeholder="password"
        {...register("password")}
      />

      {errors.password && <span>{errors.password.message}</span>}

      <button type="submit">submit!</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

还有许多关于 Zod 和表单钩子的内容,你可以查看React Hook 表单 Zod的文档,特别感谢 Austin Shelby 制作的精彩视频。

感谢您抽出时间阅读这篇简短的文章!

文章来源:https://dev.to/majiedo/using-zod-with-react-hook-form-using-typescript-1mgk