Fixes unshift and insert row not update field's state correctly #96
+21
−1
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
as reported in #44 and final-form/react-final-form-arrays#138.
This applied both
unshift
andinsert
becauseunshift
useinsert
as thisfinal-form-arrays/src/unshift.js
Lines 5 to 9 in fe3c260
I've investigated and have assumed the issue is in the following.
final-form-arrays/src/insert.js
Lines 18 to 35 in fe3c260
the logic is trying to shift the field's state to one for all fields that are greater than or equal to inserted index.
For the field's state at inserted index, it will leave as empty because there's a return statement here.
final-form-arrays/src/insert.js
Lines 26 to 37 in fe3c260
For example, if there're 4 field array items and we used
insert(2, value)
, the field's state will shifted like thisthis behavior, as I understand, it's intended and should be correct. because when the state is empty, it'll get the default state from here
https://github.com/final-form/final-form/blob/d20c44be8766b93424e7754fe2629820fd93d21a/src/FinalForm.js#L850-L866
which should set the default for the missing state. but the problem is related to React component's
key
propSince the component is rendered by each item in
fields
, as a convention and it should be, provided withname
fromfields
. so the field component is reused with the same component as the previous, one beforeinsert(2, value)
is called and after becausename
are the same. So methodregisterField
which should set the field's state as default, doesn't trigger. this makes the field's state incorrect and leads to rendering problems.I've tried to make the key unique and found that it render correctly. but as we know, this is not a good solution.
Screen.Recording.2566-06-19.at.00.30.43.mov
Here are the possible solutions I can think of
name
should not be used as a key and the final form array provides another variable for this purpose instead.Since the problem is about the rendering of components, we might need to provide a
key
which is different before and afterinsert
. But I can't think of how we should generate a key that is new every time we insert a new index but also it should be generated based on an index. This is quite a conflict. so I have no idea about this. anyways, this should be done in https://github.com/final-form/final-form-arrays and shouldn't relate here.Just remove the shifting state and keep only copy value
as suggested but this Insert does not cause array children to refresh correctly. react-final-form-arrays#138 (comment) which I still do not understand why it works as the field's state at inserted index just missing. Anyways, It might be some edge cases that lead to errors.
Add default state for the inserted field.
IMO, this might be the safest solution, which try to add default as intended. Fortunately, in the mutator, there's a helper function
resetFieldState
for resetting the field's state.My PR is to use solution 3, as far as I have checked, it has no problem. I checked with validation for the array, shows an error at submit (this is required the use of the field's state).
(the validation is, the name field must have string "t")
https://github.com/final-form/final-form-arrays/assets/13183413/5c055b9e-9046-49f9-8974-d98a99df5954
For anyone, who can't wait for the fix, and need a quick solution now (I can feel that), I provided the gist you can copy and use the functions as the mutator.
https://gist.github.com/Elecweb/7f3478b01126e40ce98492de32d3f995
I hope this can help anyone get some insight into the issue and solutions 🙏