react-hook-form: useFieldArray inconsistencies

Describe the bug While working in a feature that has a more elaborated form, I found a few problems that became unfortunately a blocker. Unless I’m missing something (which I might be, not discarding this option), those problems can be dangerous enough to not use the current lib implementation.

The feature is to have a form in a Grid shape, where fields (from useFieldArray) are the rows, and for each column I have a Controller with the name being rows[row-index].column. All the inputs are conditionally rendered based on a “Edit” toggle. Thus, instead of wrapping the Input element in the Controller, I’m wrapping the “Cell” container, so I can have access to the field errors to display them if “edit mode” is off.

Codesandbox: https://codesandbox.io/s/react-hook-form-usefieldarray-3-gy0dw (I’ve also imported the library in case you find this necessary)

Removing rows make fields to have staled value.

  1. Click on the load data button.
  2. Click on Append
  3. Delete the previous item (Ben)
  4. Recently created row, age field, will be updated to the one we removed.

Staled default values

  1. Click on the load data button.
  2. Remove all the rows
  3. Click on Append

All rows based on the values from the last reset call will be regenerated. Even if that’s the expected behaviour, calling getValues after clearing the whole form will return the latest default state. I’d argue that it should return empty as well to reflect the actual form state the user is seeing. You can verify that on line 161.

Staled object return from watch after calling reset() You can verify this from line 53 to 58.

As a side note, I’ve noted in most cases that we need to use the current field values, the recommended way is to call watch on those fields. However, I found this to impact heavily on performance, and checking the website, we don’t have any comparison with other libraries and RHF + watch. Right now, it’s comparing uncontrolled vs controlled components, which might not be fair if I may say that, because we can not notice the same experience when watching fields (specially array fields).

I appreciate if you have the time to go through this, and I’m sorry if I messed something up that is causing any of this. In this case, I’d also appreciate some guidance as I think it might be useful for others that may face this in the future.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 23 (19 by maintainers)

Most upvoted comments

@bluebill1049 The problem could resolved by passing age: null when append new values.

using his CSB: https://codesandbox.io/s/react-hook-form-usefieldarray-3-gy0dw

change line 189 to append({ nickname: `append ${fields.length}`,age: null });

Looks like the form use staled value if value is undefined, something might be wrong in useFieldArray?

I agree with you, solution 1 probably be a better DX.

Try this one

https://codesandbox.io/s/react-hook-form-usefieldarray-3-ix34q

I add an age field and change input to <Controller />. Please notice, the bug only occur when age field not have defaultValue.

To reproduce,

  1. Append new row
  2. remove second row (useFieldArray2)

The new row have age 2 (staled value)

Sure, just FYI, the author of this issue mentioned this below the codesandbox link.

Removing rows make fields to have staled value. Click on the load data button. Click on Append Delete the previous item (Ben) Recently created row, age field, will be updated to the one we removed.

@bluebill1049 Yes, the problem still exist,

  1. Click Load data,
  2. Remove last item (Ben)
  3. Click append

The inserted row still have age 51.

image