在Next.js14中结合ShadcnUI与NextUI:解决表单错误提示失效问题
在Shadcn UI Form中正确集成NextUI Input组件
问题根源
- 错误状态未结合字段触摸状态(
isTouched):react-hook-form默认仅在字段被触摸或表单提交后才暴露错误信息,未触发时不会显示错误提示。 useFormField属性解构不完整:仅获取error不足以控制错误显示逻辑,需同时结合isTouched判断。- 表单验证模式配置缺失:未明确设置验证触发时机,可能导致提交时未强制验证所有字段。
修正方案
1. 完善react-hook-form配置(可选但推荐)
在useForm中添加mode: "onSubmit",确保表单提交时强制触发所有字段验证:
import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import z from "zod"; const FormSchema = z.object({ email: z.string().min(1, "Email is required").email("Invalid email"), password: z .string() .min(1, "Password is required") .min(8, "Password must have at least 8 characters"), }); const form = useForm<z.infer<typeof FormSchema>>({ resolver: zodResolver(FormSchema), defaultValues: { email: "", password: "", }, mode: "onSubmit", // 提交时触发全量验证 });
2. 正确绑定NextUI Input与表单状态
在FormField的render回调中,完整解构useFormField返回值,将isInvalid设置为!!(error && isTouched),确保错误提示仅在合理时机显示:
import { Form, FormField } from "@/components/ui/form"; import { Input } from "@nextui-org/react"; import { useFormField } from "@/components/ui/form"; // 假设你已定义onSubmit函数 const onSubmit = (values: z.infer<typeof FormSchema>) => { console.log("提交数据:", values); // 后续业务逻辑:如API请求等 }; // 表单组件 <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)} className="w-full space-y-4"> {/* Email字段 */} <FormField control={form.control} name="email" render={({ field }) => { const { error, isTouched } = useFormField(); return ( <Input size="md" isRequired type="email" label="Email" placeholder="Enter your email" errorMessage={error?.message} isInvalid={!!(error && isTouched)} // 结合错误与触摸状态 {...field} /> ); }} /> {/* Password字段(同逻辑) */} <FormField control={form.control} name="password" render={({ field }) => { const { error, isTouched } = useFormField(); return ( <Input size="md" isRequired type="password" label="Password" placeholder="Enter your password" errorMessage={error?.message} isInvalid={!!(error && isTouched)} {...field} /> ); }} /> <button type="submit" className="w-full bg-blue-600 text-white py-2 rounded-md"> Submit </button> </form> </Form>
3. 关键逻辑说明
isTouched的作用:避免页面初始化时就显示错误提示,提升用户体验;若希望提交后无论是否触摸都显示错误,可将isInvalid改为!!error。- 类型安全优化:避免使用
any类型,可给field添加明确类型:{ field: ControllerRenderProps<z.infer<typeof FormSchema>, "email"> }(需从react-hook-form导入ControllerRenderProps)。 - NextUI属性映射:NextUI的
Input会在isInvalid为true时自动显示errorMessage,无需额外手动控制显示逻辑。
内容的提问来源于stack exchange,提问作者Viet Quang Fresher
相关产品推荐
相关产品推荐

