简体   繁体   English

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

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

I'm making a nested form builder that is dynamic.我正在制作一个动态的嵌套表单生成器。

This is the current project I'm working on: https://codesandbox.io/s/ava-dynamic-react-hook-form-ivgt40?file=/src/App.js这是我正在处理的当前项目: https://codesandbox.io/s/ava-dynamic-react-hook-form-ivgt40?file=/src/App.js

The issue I'm having is that when I swap or delete Groups, the values within the Group aren't properly set.我遇到的问题是,当我交换或删除组时,组内的值设置不正确。

I believe it is due to the {...register()} and the altering ref on my Input Components, but I am not certain.我相信这是由于 {...register()} 和输入组件上的更改 ref 造成的,但我不确定。

The form data.js file in the linked project at the top contains the form structure I wish to render.顶部链接项目中的表单 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,
        }
    }
}

State management State 管理

You seem to be mixing places to that are keeping tracking of state.您似乎正在混合跟踪 state 的地方。

You basicly have 2 types of state你基本上有 2 种类型的 state

  • State of the form values |表格值的 State | this is stored in the react-hook-form这存储在react-hook-form
  • State of the sort order of form inputs | State 表单输入的排序顺序| this is stored in your Element.jsx这存储在您的Element.jsx

By mixing these, you have to manually make sure they stay in sync通过混合这些,您必须手动确保它们保持同步

react-hook-form反应挂钩形式

When you're using react-hook-form .当你使用react-hook-form时。 you're entrusting some state management to that hook.您将一些 state 管理委托给该挂钩。 They provide an API through register to keep track of the fields and values for the form.他们通过寄存器提供 API 以跟踪表单的字段和值。

Register takes a name as the first param. Register 将名称作为第一个参数。
This is the only handle you have for the form to identify fields.这是表单识别字段的唯一句柄。
A new name would be a new fields.新名称将是新字段。

the problem问题

You're not keeping things in sync.你没有保持同步。
Changing the order will do a couple of things:改变顺序会做几件事:

  • The current elementIdPath is something like Emailprofile.0.notifications.0.email.0.email-abcd123当前的elementIdPath类似于Emailprofile.0.notifications.0.email.0.email-abcd123
  • Emailprofile.0.notifications.0.email.0.email-abcd123 is passed as name to the register. Emailprofile.0.notifications.0.email.0.email-abcd123作为名称传递给寄存器。
  • click on the change order button单击更改订单按钮
  • handleSwapListElements runs and changes the element via setElementItem handleSwapListElements运行并通过setElementItem更改元素
  • the elementIdPath changes: Emailprofile.0.notifications.0.email.1.email-abcd123 (notice index change from 0 to 1) elementIdPath更改: Emailprofile.0.notifications.0.email.1.email-abcd123 (通知索引从 0 更改为 1)
  • New name is registerd and treated as a new field注册新名称并将其视为新字段
  • the old field is also still registered and in state. clicking submit will also have the old name and value.旧字段也仍然在 state 中注册。单击提交也将具有旧名称和值。

The fix修复

Keep the sort order and values in sync.保持排序顺序和值同步。 You'll have to decide yourself how exactly to do that.你必须自己决定具体怎么做。 either:任何一个:

  • don't include sort order or indexes as key in the name.不要在名称中包含排序顺序或索引作为键。
  • manually keep things in sync using react-hook-form methods.使用react-hook-form方法手动保持同步。

Both have their ups and downs.两者都有起伏。

not including indexes as key不包括索引作为键

A dynamic form without indexes would require you to attach all that information on the field itself.没有索引的动态表单将要求您将所有信息附加到字段本身。 Basically you would register a unique key (uuid), and keep track of the uuid path yourself.基本上,您会注册一个唯一密钥 (uuid),并自己跟踪 uuid 路径。
IE you register to properties.: 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. 
 }

manually keep things in sync using react-hook-form methods.使用react-hook-form方法手动保持同步。

Whenever you change the name of a field, you would get the current value.每当您更改字段name时,您将获得当前值。 unregister the old name and set the value on the new name.注销旧名称并在新名称上设置值。
react-hook-form exposes a method from the hook for that. react-hook-form公开了一个钩子方法。

unregister and setValue注销设置值

If it where up to me, and seeing your code.I would probably try to go in this direction as opposed to refactoring to things to remove the indexes from name.如果由我决定,并查看您的代码。我可能会朝这个方向尝试 go,而不是重构事物以从名称中删除索引。

sandbox沙箱

this sandbox with modifications should paint the picture.这个经过修改的沙箱应该可以描绘出画面。 It will not properly work yet for the base elements, but the nodes at profile.0.notification.0.email should function.对于基本元素,它还不能正常工作,但是profile.0.notification.0.email中的节点应该是 function。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM