react-hook-form实现中handleSubmit不触发且报ref警告如何解决?
问题原因
该问题核心是react-hook-form的register方法使用逻辑和Input组件的属性不匹配:
register方法返回的对象包含onChange、onBlur、ref三个必填属性,用于同步控件状态到表单实例- 你把
register返回的完整对象直接赋值给了innerRef属性,导致react-hook-form无法正确获取输入框引用,也无法同步输入值,校验逻辑失效后自然不会触发onSubmit回调,同时抛出ref类型不匹配的警告 - 手动绑定的
onChange、value={price}属于受控组件写法,和react-hook-form默认的非受控注册逻辑冲突,也会导致状态同步异常
解决方法
方案1:不需要自定义维护price状态(推荐)
直接拆分register返回的属性,手动指定ref挂载到innerRef上即可:
const { register, handleSubmit, formState: { errors } } = useForm({ resolver: yupResolver(schema), }); // 拆分ref和其他属性 const { ref: voucherPriceRef, ...voucherPriceRest } = register("voucherPrice", { required: true }) const onSubmit = (data) => { console.log("?", data); }
表单代码修改为:
<form onSubmit={handleSubmit(onSubmit)}> <Input type="number" innerRef={voucherPriceRef} {...voucherPriceRest} ></Input> <p>{errors.voucherPrice?.message}</p> <Button variant="contained" sx={{ mt: 1, mr: 1 }} type="submit" > Continue </Button> </form>
方案2:需要保留自定义price状态和onChange逻辑
使用Controller组件适配受控组件写法:
import { Controller, useForm } from 'react-hook-form'; // 原有自定义逻辑保留 const [price, setPrice] = useState(0); const handlePriceInputChange = (ev) => { setPrice(ev.target.value) } const { control, handleSubmit, formState: { errors } } = useForm({ resolver: yupResolver(schema), }); const onSubmit = (data) => { console.log("?", data); }
表单代码修改为:
<form onSubmit={handleSubmit(onSubmit)}> <Controller name="voucherPrice" control={control} rules={{ required: true }} render={({ field }) => ( <Input onChange={(ev) => { field.onChange(ev); handlePriceInputChange(ev); }} type="number" value={price} innerRef={field.ref} /> )} /> <p>{errors.voucherPrice?.message}</p> <Button variant="contained" sx={{ mt: 1, mr: 1 }} type="submit" > Continue </Button> </form>
修改后ref绑定逻辑正常,表单校验和提交回调即可正常触发。
内容的提问来源于stack exchange,提问作者Gotey
相关产品推荐
相关产品推荐

