react-hook-form用useFormContext取register报not a function错误如何解决?
问题根因
- FormProvider未正确传值:react-hook-form的
FormProvider组件必须接收useForm()返回的所有方法作为props,你当前没有传入任何参数,导致子组件调用useFormContext()时拿不到正确的register方法,自然报错register is not a function。 - 字段名称未关联数组索引:Item组件里的输入框名称没有拼接当前条目索引,会导致多条目输入时字段名冲突,所有值会被覆盖,最终提交的invoices数组只会拿到最后一条的数据。
修复步骤
1. 修改CreateInvoice.js中的FormProvider调用
把useForm返回的所有方法展开传给FormProvider,你可以直接把CreateInvoice里的useForm调用改成赋值给methods变量,更方便:
// 替换原来的useForm行 const methods = useForm(); const { register, control, handleSubmit, errors } = methods;
然后对应的FormProvider改成:
<FormProvider {...methods}>
2. 修改Item.js中的输入框name属性
把每个输入框的inputName拼接上当前条目索引,关联到invoices数组对应位置的字段:
const Item = ({ index, remove }) => { const { register } = useFormContext(); return ( <div className="flex justify-center items-end"> <div className="w-3/5"> <Label labelName="Item Name" /> <Input inputName={`invoices[${index}].itemName`} register={register} /> </div> <div className="w-2/12 mx-3"> <Label labelName="Qty." /> <Input inputName={`invoices[${index}].quantity`} register={register} /> </div> <div className="w-1/3"> <Label labelName="Price" /> <Input inputName={`invoices[${index}].price`} register={register} /> </div> <div className="mx-3"> <Label labelName="Total" /> <Input inputName={`invoices[${index}].total`} register={register} readOnly /> </div> {/* 其余删除按钮代码不变 */} </div> ) }
额外说明
你之前在Item里直接调用useForm不报错的原因是,单独调用useForm会创建一个独立的表单实例,和父组件的表单完全不关联,所以父组件的invoices数组只会拿到空对象,子组件输入的内容不会同步到父表单的提交数据里,修复之后父子组件共用同一个表单实例,所有条目输入的内容都会正确同步到invoices数组中。
内容的提问来源于stack exchange,提问作者r121
相关产品推荐
相关产品推荐

