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
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.
The form data.js file in the linked project at the top contains the form structure I wish to render.
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,
}
}
}
You seem to be mixing places to that are keeping tracking of state.
You basicly have 2 types of state
react-hook-form
Element.jsx
By mixing these, you have to manually make sure they stay in sync
When you're using react-hook-form
. you're entrusting some state management to that hook. They provide an API through register to keep track of the fields and values for the form.
Register takes a name as the first param.
This is the only handle you have for the form to identify fields.
A new name would be a new fields.
You're not keeping things in sync.
Changing the order will do a couple of things:
elementIdPath
is something like Emailprofile.0.notifications.0.email.0.email-abcd123
Emailprofile.0.notifications.0.email.0.email-abcd123
is passed as name to the register. handleSwapListElements
runs and changes the element via setElementItem
elementIdPath
changes: Emailprofile.0.notifications.0.email.1.email-abcd123
(notice index change from 0 to 1) Keep the sort order and values in sync. You'll have to decide yourself how exactly to do that. either:
react-hook-form
methods.Both have their ups and downs.
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.
IE you register to properties.:
{
"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
methods. Whenever you change the name
of a field, you would get the current value. unregister the old name and set the value on the new name.
react-hook-form
exposes a method from the hook for that.
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.