Remove is not working with nested field arrays on 6.15.2 and above

Describe the bug
When using nested field array, remove has stopped working properly on version 6.15.2 and 6.15.3.
Calling remove on the parent field array is not behaving as expected. Instead, the fields are somehow being replaced with empty fields while maintaining the same array length. Also, the field id undefined for the new fields.

I created a minimal CodeSandbox to demonstrate the bug:

To Reproduce
Steps to reproduce the behavior:

  1. Go to the CodeSandbox provided below.
  2. Click on add child.
  3. Click on remove child.
  4. The child is not removed and react will show a warning saying Warning: Each child in a list should have a unique "key" prop.
  5. downgrade to version 6.15.1
  6. add children and nested children and remove them.
  7. notice how no errors are shown and that remove is behaving as expected!

Codesandbox link (Required)
https://codesandbox.io/s/hook-form-nested-field-array-t4m3g?file=/src/App.js

Expected behavior
Remove should behave like it did before on earlier versions.

Desktop (please complete the following information):

  • OS: macOS
  • Chrome 88
  • 6.15.3

Additional context
I might be wrong, but I think this is related to #4172

2 thoughts on “Remove is not working with nested field arrays on 6.15.2 and above

  1. @Elia-Darwish @bluebill1049

    It seems the root cause is from line 511 in useFieldArray.ts, not from #4172.

    return () => {
    isUnMount.current = true;
    shouldUnregister && remove();
    resetFields();
    delete resetFunctions[name];
    unset(fieldArrayValuesRef, name);
    fieldArrayNames.delete(name);

    It should be

    unset(fieldArrayValuesRef.current, name);
    

    But fixing this line it’s not enough because it will lead into another issue where “fieldArrayValuesRef.current” after appending new item is something like:

    {
       children: [{ ...First added item }]
    }
    
    

    When removing that item, with the name is “children[0].nested” in this case, the method “unset” from utils/unset.ts only removes item reference by using native method “delete” therefore array “children” will be empty but its length is still 1. It will lead into undefined error when trying to add child again because position “0” is now undefined and the new added item will be at position “1”.

    {
      children: [ undefined, {... Second added item }]
    }
    

    previousObjRef ? delete previousObjRef[item] : delete object[item];

    @bluebill1049 : Can we use Array.prototype.splice() if the target object to be unset is an array ?