Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(form): prevent reload loop with rjsf v5.20 #75

Closed

Conversation

miguelgrc
Copy link
Collaborator

@miguelgrc miguelgrc commented Sep 12, 2024

Closes #72

rjsf 5.20 was causing issues with our e2e tests since sometimes, when dragging new (e.g. select) fields to the tree some of them would be typed as text fields. This is related to our use of rawErrors in the our custom validation function to pass down the path to FieldTemplate.

It turns out the error was being caused by this change in rjsf. That mergeObjects there with the preventDuplicates argument returns a deep copy of the object when called with two equal objects, meaning that the errorSchema object returned is essentially a new one. properties.content.props in ObjectFieldTemplate contains errorSchema, therefore it reloads when the errorSchema changes (after that change in rjsf it now does so on every validation call), causing cards to change, causing the uiSchema to be updated in the store, causing the Form in SchemaTree to refresh (as uiSchema is an object and useSelector uses a shallow equality check*), triggering a new validation, and continuing the endless loop.

The solution has been to add an extra check in ObjectFieldTemplate so that changes in cards only dispatch an update to the uiSchema when the order of the cards changes, and not in every situation when the cards array changes (which in fact happens on every re-render as it's an array and arrays are compared by reference, returning false even if both arrays have the same content, which is generally the case here). This breaks that loop.

Note: The way we use rawErrors to pass the path to the FieldTemplate is a bit hackish, but seeing that it keeps working after this change I would maintain it for the time being. There is no rjsf way of getting the path information functions such as toPathSchema only return the "path" from the current element to its children, but not from the root to the current element, which is what we need. So, the alternative, if we end up wanting to change this, could be to have a paths object in the redux store and populate it in the addByPath action, and we also would have to populate it on startup when loading an existing schema by traversing it completely. We would also have to disallow duplicate field ids everywhere in the form.

*We should consider using Immer for the Redux state to better protect ourselves against these situations

@pamfilos
Copy link
Collaborator

Merged with #77

@pamfilos pamfilos closed this Sep 23, 2024
@miguelgrc miguelgrc deleted the fix-field-types-rjsf5.20 branch September 30, 2024 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rjsf v5.20.0 breaking field types and tests
2 participants