React Hook Form设为onBlur模式时如何实现表单自动提交?
失焦时自动提交React Hook Form表单
问题背景
需要实现一个无提交按钮的表单,要求输入框失焦时自动提交表单。当前已配置React Hook Form的mode: "onBlur",但输入框失焦后并未触发handleSave函数,需解决自动提交的实现方式。
解决方案
React Hook Form的onBlur模式仅负责触发表单校验,不会自动执行提交逻辑,因此需要手动触发提交动作,以下是两种可行方案:
方案一:利用输入框的onBlur回调手动触发提交
通过给每个输入字段绑定onBlur回调,在失焦时校验表单有效性,通过后提交表单。
import { useForm, useRef } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import z from "zod"; // 定义Zod校验规则 const saveInputSchema = z.object({ name: z.string().min(1, "名称不能为空"), }); type TSaveInputSchema = z.infer<typeof saveInputSchema>; export default function AutoSubmitForm() { const formRef = useRef<HTMLFormElement>(null); const { formState: { isValid }, handleSubmit, register } = useForm<TSaveInputSchema>({ mode: "onBlur", reValidateMode: "onChange", criteriaMode: "firstError", resolver: zodResolver(saveInputSchema), }); // 提交处理函数 const handleSave = (data: TSaveInputSchema) => { console.log("提交的数据:", data); }; // 失焦时触发提交逻辑 const handleInputBlur = async () => { if (await isValid) { formRef.current?.submit(); } }; return ( <form ref={formRef} onSubmit={handleSubmit(handleSave)}> <input {...register("name", { onBlur: handleInputBlur })} placeholder="请输入名称" /> </form> ); }
方案二:监听表单状态自动提交
通过useEffect监听表单的isValid(是否有效)和dirtyFields(是否有修改)状态,当满足条件时自动触发提交。
import { useForm, useEffect } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import z from "zod"; const saveInputSchema = z.object({ name: z.string().min(1, "名称不能为空"), }); type TSaveInputSchema = z.infer<typeof saveInputSchema>; export default function AutoSubmitForm() { const { formState: { isValid, dirtyFields }, handleSubmit, register, getValues } = useForm<TSaveInputSchema>({ mode: "onBlur", reValidateMode: "onChange", criteriaMode: "firstError", resolver: zodResolver(saveInputSchema), }); const handleSave = (data: TSaveInputSchema) => { console.log("提交的数据:", data); }; const onSubmit = handleSubmit(handleSave); useEffect(() => { // 表单有效且存在修改字段时触发提交 if (isValid && Object.keys(dirtyFields).length > 0) { onSubmit(getValues()); } }, [isValid, dirtyFields, onSubmit, getValues]); return ( <form> <input {...register("name")} placeholder="请输入名称" /> </form> ); }
注意事项
- 方案一适合单字段或少量字段场景,触发时机更精准(仅当前字段失焦时)
- 方案二适合多字段场景,任何字段失焦后只要表单有效且有修改就会提交,需注意避免初始加载时误触发
- 两种方案都需先校验表单有效性,避免提交不符合规则的数据
内容的提问来源于stack exchange,提问作者Yanick Rochon
相关产品推荐
相关产品推荐

