如何使用react-hook-form+zod实现动态表单验证?-灵析社区

Midclimateeee

如何使用react-hook-form+zod实现动态表单验证?比如登陆时不需要输入邮箱,注册时需要输入邮箱 {variant === "Register" && ( 邮箱 {errors.email && ( {errors.email.message} )} )} 大概的样子: ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250103/4f41b5e304408bc9028e197271ab9de2.png) ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250103/17bcbde58926d38116e16fcd43ea9d1b.png) 以下是完整代码,无法实现对 `email` 项的校验 "use client"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; const LoginFormSchema = z.object({ username: z .string() .min(3, { message: "用户名不得少于3个字符", }) .max(20, { message: "用户名不得多于20个字符", }), password: z .string() .min(8, { message: "密码不得少于8个字符", }) .max(20, { message: "密码不得多于20个字符", }), }); const RegisterFormSchema = z.object({ email: z.string().email({ message: "邮箱格式不正确", }), username: z .string() .min(3, { message: "用户名不得少于3个字符", }) .max(20, { message: "用户名不得多于20个字符", }), password: z .string() .min(8, { message: "密码不得少于8个字符", }) .max(20, { message: "密码不得多于20个字符", }), }); const FormSchema = z.union([LoginFormSchema, RegisterFormSchema]); type FormSchemaType = z.infer; const UserForm = () => { const [variant, setVariant] = useState("Login"); const { register, handleSubmit, formState: { errors, isSubmitting }, watch, } = useForm({ resolver: zodResolver(FormSchema), defaultValues: { username: "", password: "", }, }); const onSubmit = async (data: FormSchemaType) => { await new Promise((resolve) => setTimeout(resolve, 1000)); }; return ( {variant === "Login" ? "登录" : "注册"} {variant === "Register" && ( 邮箱 {errors.email && ( {errors.email.message} )} )} 用户名 {errors.username && ( {errors.username.message} )} 密码 {errors.password && ( {errors.password.message} )} {variant === "Login" ? "还没有账号?去" : "已有账号?去"} setVariant(variant === "Login" ? "Register" : "Login") } > {variant === "Login" ? "注册" : "登录"} 提交 {JSON.stringify(watch(), null, 2)} ); }; export default UserForm;

阅读量:199

点赞量:13

问AI
在 "schema email" 中添加 "optional()" 选项 "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250102/bcc4e773636d098bee29630a89de13a0.png) "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250102/90a1d682c863ca51b59fdd8418ac7030.png) 修改过后的完整代码: "use client"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; const FormSchema = z.object({ email: z .string() .email({ message: "邮箱格式不正确", }) .optional(), username: z .string() .min(3, { message: "用户名不得少于3个字符", }) .max(20, { message: "用户名不得多于20个字符", }), password: z .string() .min(8, { message: "密码不得少于8个字符", }) .max(20, { message: "密码不得多于20个字符", }), }); type FormSchemaType = z.infer; const UserForm = () => { const [variant, setVariant] = useState("Login"); const { register, handleSubmit, formState: { errors, isSubmitting }, watch, } = useForm({ resolver: zodResolver(FormSchema), }); const onSubmit = async (data: FormSchemaType) => { await new Promise((resolve) => setTimeout(resolve, 1000)); }; return ( {variant === "Login" ? "登录" : "注册"} {variant === "Register" && ( 邮箱 {errors.email && ( {errors.email.message} )} )} 用户名 {errors.username && ( {errors.username.message} )} 密码 {errors.password && ( {errors.password.message} )} {variant === "Login" ? "还没有账号?去" : "已有账号?去"} setVariant(variant === "Login" ? "Register" : "Login") } > {variant === "Login" ? "注册" : "登录"} 提交 {JSON.stringify(watch(), null, 2)} ); }; export default UserForm;