You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm attempting to add UI/components that modify form state directly.
Making the whole form 'controlled' (in the React sense) by a wrapping component, ie by tying RJSF Form formData and onChange to React.useState, seems to mostly work. The form data can be modified in the wrapper component via the state setter and responds mostly how I'd like. However, I've run into problems with array field key stability. I'll get into details of that below, but it might be an XY problem if there's a better way to take control of form data:
Is this kind of 'controlled' RJSF form an intended/supported use case?
(The docs seem to imply that the formData prop to Form is only to set default/initial data; perhaps using it this way is a stretch?)
Are there any preferred alternatives?
(I've considered using an ArrayField custom field and going through its onChange; but this still runs into the key stability issue; going through the array items themselves wouldn't allow eg an append)
The array key stability problem:
Assuming the controlled form setup above, when the form data is updated by calling the state setter (from React.useState), it clobbers the stable keys that the ArrayField sets up internally, ie the ones implemented in #1335 to fix #1046 . As a result they get reset on re-render, and open the door to symptoms that #1335 hoped to prevent.
As a concrete example of what can break: a custom ArrayFieldTemplate with item add/remove animations via react-transition-group might key the transitions off the array item key; when the keys get clobbered, the next array item add animates as if all items (including existing ones) are being newly added.
A work-around?
A (very fragile) work-around is to pass a key remapper function down through eg formContext and having a custom ArrayField field/template call it on re-render, and use the remapped keys as the actual array item keys:
That function then has to do a bit of a dance to map "new" internal keys to the old/stable ones, coordinated to any "clobbering" form data change. It might use the indices to do this, but has to be very careful to use those indices 'safely' relative to the actual form data change operation. This... works... but it is a lot of complexity and fragility.
Is there a cleaner way to accomplish this?
Thank you very much for the library, and for your help!
The text was updated successfully, but these errors were encountered:
mike-capyh
changed the title
How to Preserve Array Field Key Stability When Changing Form Data via onChange?
How to Preserve Array Field Key Stability When Changing Form Data in a Controlled Form?
Nov 23, 2024
Prerequisites
What theme are you using?
mui
What is your question?
I'm attempting to add UI/components that modify form state directly.
Making the whole form 'controlled' (in the React sense) by a wrapping component, ie by tying RJSF Form
formData
andonChange
toReact.useState
, seems to mostly work. The form data can be modified in the wrapper component via the state setter and responds mostly how I'd like. However, I've run into problems with array field key stability. I'll get into details of that below, but it might be an XY problem if there's a better way to take control of form data:formData
prop toForm
is only to set default/initial data; perhaps using it this way is a stretch?)ArrayField
custom field and going through itsonChange
; but this still runs into the key stability issue; going through the array items themselves wouldn't allow eg an append)The array key stability problem:
Assuming the controlled form setup above, when the form data is updated by calling the state setter (from
React.useState
), it clobbers the stablekey
s that theArrayField
sets up internally, ie the ones implemented in #1335 to fix #1046 . As a result they get reset on re-render, and open the door to symptoms that #1335 hoped to prevent.As a concrete example of what can break: a custom
ArrayFieldTemplate
with item add/remove animations viareact-transition-group
might key the transitions off the array item key; when the keys get clobbered, the next array item add animates as if all items (including existing ones) are being newly added.A work-around?
A (very fragile) work-around is to pass a key remapper function down through eg
formContext
and having a customArrayField
field/template call it on re-render, and use the remapped keys as the actual array item keys:That function then has to do a bit of a dance to map "new" internal keys to the old/stable ones, coordinated to any "clobbering" form data change. It might use the indices to do this, but has to be very careful to use those indices 'safely' relative to the actual form data change operation. This... works... but it is a lot of complexity and fragility.
Is there a cleaner way to accomplish this?
Thank you very much for the library, and for your help!
The text was updated successfully, but these errors were encountered: