How to preserve hidden fields in react-hook-form fieldArray?

20.9k views Asked by At

I'm trying to build list of forms based on array of objects, those objects have fields that should have the ability to be edited, and be rendered as inputs, and readonly fields that don't need to be rendered, for example id.

I do that by using useFieldArray hook. However, react hook seems to save only those fields that are registered as inputs, which results in my id field getting lost in submit handler.

How do I preserve my readonly fields?

Here's sandbox example, so you can get what I am talking about. I added id to default value and to value that gets appended. When you click submit id is no longer there.

2

There are 2 answers

2
NearHuscarl On BEST ANSWER

Use <input type='hidden' /> for fields you don't want to display to user like user ID and register as normal. So in your code you should add another input for id like this:

<input type="hidden" {...register(`test[${index}].useId`)} />

This is just like when you set display: none, but the field value is still submitted.

Live Demo

Codesandbox Demo

2
Nitesh On

Following are my findings, may be it can help-:

You need to add the hidden field in the default array while adding a new row,so that it will be added in the newly created object which reference the newly added row and while sending data to backend, the hidden field value will also be sent.

export const addNewElement = (newElement: any, array: any, setArray: any) => {
//get a unique id
   const id = incrementUntilNotPresent(array)
       setArray((prevArray: any) => [...prevArray, { id, ...newElement }])
}



addNewElement(
                    { hiddenField: value },
                    rows,
                    setRows
                )


const [rows, setRows]=useState(data source)

rows is default value for useForm(contains data for a dynamic form having multiple fields in a row, same can be used for a form with single field) i.e data shown in the form UI initially and will contain the hidden field after calling addNewElement(), which now can be send to backend.

Hope this helps.