React Hook Form结合Server Actions时的表单预验证问题
可以借助React Hook Form在提交到服务器前完成表单验证
即使使用form的action属性调用Server Action,依然可以通过RHF的验证能力在提交前完成前端校验,核心是结合RHF的handleSubmit和form的onSubmit事件来实现:
实现步骤
- 从
useForm中取出handleSubmit方法,它会自动处理RHF的验证规则,验证失败时阻止后续提交并更新错误状态。 - 给form添加
onSubmit事件,用handleSubmit包裹自定义的提交逻辑。 - 验证通过后,可选择让form默认的
action提交逻辑执行,或者手动调用formAction并阻止默认提交。
代码示例
import { useForm, Controller } from "react-hook-form"; import { useActionState } from "react"; type Tenant = { name: string; }; // 假设你的Server Action async function createTenant(prevState: any, formData: FormData) { // 服务器端逻辑 } export default function TenantForm() { const { control, handleSubmit, formState: { errors } } = useForm<Tenant>({ defaultValues: { name: "", }, // 可选:设置实时验证模式,比如输入时验证 mode: "onChange", }); const [state, formAction] = useActionState(createTenant, null); // 验证通过后的处理逻辑 const onValidSubmit = async (data: Tenant, e: React.FormEvent<HTMLFormElement>) => { // 方式1:手动调用Server Action,阻止默认提交 e.preventDefault(); await formAction(new FormData(e.currentTarget)); // 方式2:不调用preventDefault,让form默认的action提交逻辑执行 // 此时不需要手动调用formAction,浏览器会自动将表单数据传给action指定的Server Action }; return ( <form action={formAction} onSubmit={handleSubmit(onValidSubmit)}> <Controller name="name" control={control} rules={{ required: "请输入公司名称" }} render={({ field, fieldState: { error } }) => ( <div> <label htmlFor="name">公司名称</label> <input id="name" type="text" {...field} className={error ? "border-red-500" : ""} /> {error && <p className="text-red-500">{error.message}</p>} </div> )} /> <button type="submit">提交</button> </form> ); }
关键说明
handleSubmit会自动触发RHF的规则验证,验证失败时会:- 阻止后续的提交逻辑(不管是默认action还是手动调用)
- 更新
fieldState.error状态,显示对应的错误提示
- 如果你需要实时验证(比如用户输入时就显示错误),可以在
useForm配置中设置mode参数(可选值:onChange/onBlur/onSubmit等) - 手动调用
formAction时,需要把表单数据转换成FormData格式(和浏览器默认提交的格式一致),确保Server Action能正确接收数据
内容的提问来源于stack exchange,提问作者Joshua Bolk
相关产品推荐
相关产品推荐

