You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Hook Form封装高阶组件动态表单提交无法提取输入数据问题

问题原因

你提交时只能拿到空数据的核心原因是项目中存在两个完全隔离的react-hook-form实例:

  • 父组件member-registration-form.tsx中调用useForm创建了第一个实例,提交事件绑定的是这个实例
  • HOC内部又调用useForm创建了第二个完全独立的实例,所有动态输入框都绑定在这个实例上
    两个实例的状态互不连通,父组件自然拿不到子组件内的输入值。同时HOC内部嵌套了<form>标签,不符合HTML表单嵌套规范,也会导致提交行为异常。

修复步骤

1. 改造父组件,统一管理表单实例

将表单默认值移到父组件的useForm中配置,同时把control和register透传给OrderList组件:

import OrderList from "../components/orderList";
import { useForm, SubmitHandler } from "react-hook-form";
import React from "react";

const MemberRegistration = () => {
  const { register, handleSubmit, control } = useForm({
    defaultValues: {
      test: [{ firstName: "Bill", lastName: "Luo" }]
    }
  });

  return (
    <form onSubmit={handleSubmit(data => console.log(data))}>
      <OrderList control={control} register={register} />
      <input type="submit" />
    </form>
  );
};

export default MemberRegistration;

2. 改造HOC,移除内部独立表单实例

删除HOC内部的useForm调用,改用父组件透传的实例方法,同时删掉嵌套的<form>标签:

import { useFieldArray } from "react-hook-form";
const hoc = (WrappedComponent) => {
  return (props) => {
    const { control, register } = props;

    const { fields, append, prepend, remove } = useFieldArray({
      control,
      name: "test"
    });

    return (
      <div>
        <ul>
          {fields.map((item, index) => (
            <WrappedComponent
              key={item.id}
              item={item}
              removeindex={remove}
              index={index} 
              register={register}
            />
          ))}
        </ul>
        <section>
          <button
            type="button"
            onClick={() => {
              append({ firstName: "appendBill", lastName: "appendLuo" });
            }}
          >
            append
          </button>
        </section>
      </div>
    );
  };
};
export default hoc;

可选优化:多层嵌套场景用FormProvider

如果你的表单嵌套层级很深,逐层透传props比较麻烦,可以用react-hook-form提供的FormProvider做全局状态共享:

  • 父组件用FormProvider包裹子组件,传入所有useForm返回的方法
  • 子组件通过useFormContext()直接获取全局表单实例,不需要逐层传props

内容的提问来源于stack exchange,提问作者Kasun Wickramanayake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:45:04