交换或删除组时,React Hook Form 值不会改变

React Hook Form value is not changing when swapping or Deleting Groups

我正在制作一个动态的嵌套表单生成器。

这是我目前正在进行的项目:https://codesandbox.io/s/ava-dynamic-react-hook-form-ivgt40?file=/src/App.js

我遇到的问题是,当我交换或删除组时,组内的值设置不正确。

我认为这是由于 {...register()} 和输入组件上的更改 ref 造成的,但我不确定。

顶部链接项目中的表单 data.js 文件包含我希望呈现的表单结构。

list: {
    id,
    label,
    control: "list" // identifier that this element is a list
    creatable: boolean,
    items: [
        [elements], // group 1
        [elements], // group 2
    ]
}
input: {
    id,
    label,
    control: "input" // identifier that this element is a input
    type: "text" // type of input
    defaultValue,
    rules: {
        required: {
            value: boolean,
            message: string,
        }
    }
}

状态管理

您似乎在混合跟踪状态的地方。

你基本上有两种状态

  • 表格值的状态 |这存储在 react-hook-form
  • 表单输入的排序状态 |这存储在您的 Element.jsx

通过混合这些,您必须手动确保它们保持同步

react-hook-form

当您使用 react-hook-form 时。你将一些状态管理委托给那个钩子。 他们通过 register 提供 API 来跟踪表单的字段和值。

Register 以 name 作为第一个参数。
这是表单识别字段的唯一句柄。
新名称就是新字段。

问题

你没有保持同步。
更改顺序将执行以下操作:

  • 当前的 elementIdPath 类似于 Emailprofile.0.notifications.0.email.0.email-abcd123
  • Emailprofile.0.notifications.0.email.0.email-abcd123 作为名称传递给寄存器。
  • 单击更改订单按钮
  • handleSwapListElements 通过 setElementItem
  • 运行并更改元素
  • elementIdPath变化:Emailprofile.0.notifications.0.email.1.email-abcd123(通知索引从0变为1)
  • 新名称已注册并被视为新字段
  • 旧字段也仍处于注册状态。单击提交也将具有旧名称和值。

修复

保持排序顺序和值同步。你必须自己决定具体怎么做。 或者:

  • 不要在名称中包含排序顺序或索引作为键。
  • 使用 react-hook-form 方法手动保持同步。

两者各有优缺点。

不包括索引作为键

没有索引的动态表单需要您将所有信息附加到字段本身。 基本上你会注册一个唯一的密钥(uuid),并自己跟踪 uuid 路径。
IE你注册到属性。:

 {
   "abcd123-value" : "some@email.de",
   "abcd123-path"  : "Emailprofile.0.notifications.0.email.0.email-abcd123" // this would not be shown to the user, but still exposed to the form, in the submit you would manually combine the information again. 
 }

使用 react-hook-form 方法手动保持同步。

每当您更改字段的 name 时,您将获得当前值。 注销旧名称并在新名称上设置值。
react-hook-form 从钩子中公开了一个方法。

unregistersetValue

如果由我决定,看到您的 code.I 可能会尝试朝这个方向前进,而不是重构事物以从名称中删除索引。

沙盒

这个 sandbox with modifications 应该画图。 对于基本元素,它还不能正常工作,但 profile.0.notification.0.email 处的节点应该可以正常工作。