Hello,
Firstly, thank you for this excellent package. We’ve been using JsonForms in our project for quite some time and truly appreciate its flexibility and integration with React.
This works fine—prev always holds the latest data. Additionally, we also trigger setFormData from within the onChange of JsonForms to maintain consistency with our internal state.
Concern
While this setup generally works as expected, we have noticed a random and inconsistent issue where the data received by props in the onChange callback from JsonForms does not reflect the latest state updates from outside (i.e., the latest setFormData calls). This causes form data to become out of sync occasionally.
Questions
Is it expected behavior for onChange in JsonForms to be triggered even when data is updated externally via setState?
Is it considered good practice to call setFormData from within the onChange handler, or could that be causing unintended side effects?
Could this be a timing issue between external updates and internal state handling within JsonForms, or is there any known limitation related to this pattern?
Goal
I want to understand whether this behavior is expected or if there might be a misconfiguration in how we’re handling state updates in conjunction with JsonForms.
Any insights or suggestions on best practices for managing form state updates with JsonForms in React would be highly appreciated.
The issue overall comes from the fact that JSON Forms has an internal state. This internal state handling is quite optimized for the common usage patterns, however for edge cases you might run into issues, like you do.
Generally we would like to offer a clear distinction between a “controlled” and an “uncontrolled” JSON Forms, like the Material UI renderers themselves do, but we are not there yet. So at the moment, if you are just using JsonForms you are using a “mixed” approach.
Whenever new data is handed over to JSON Forms, JSON Forms will validate it and emit a new onChange event with the data and the validation result. The exception is when you hand over the data which was previously emitted by JSON Forms itself. JSON Forms will recognize that it’s the same data it already stores, and therefore not emit an event.
Normally that is completely fine, and usually I even recommend it. However if you never sync outside data into JSON Forms, i.e. all the changes to the form data is performed by the user in your renderers, then you don’t need to do it.
Yes, this seems like the issue you are facing and it’s likely caused by the “mixed” approach of JSON Forms. The good news is that there is an escape hatch for you. Using the middleware support of JSON Forms, you can convert the usage of JSON Forms into a “controlled” approach. As you fully manage the data then, you will no longer run into issues when syncing external and internal updates.
See this guide on how to leverage the middleware support to achieve “controlled” style. The example uses hard coded validation. In your case you should rust run AJV.
Using this you can fully control data and errors and you’re no longer depending on onChange.
I hope this helps, let me know if you run into issues.
@sdirix, thank you for your response.
Using middleware and custom validation isn’t an ideal fit for our project requirements, as the issue originates within a specific component where setFormData is being triggered multiple times due to its internal functionality. We have attempted to control this behavior and have partially addressed it for now. We hope that JSONForms will handle this edge case more robustly in future updates.
can you detail why this would not be a fit? Leveraging JSON Forms this way makes it 100% controlled, so it should meet your requirements. Are you struggling with the integration? Would it be helpful if the guide showed how to properly leverage AVJ in this scenario?
With this wrapper I would expect that you could just drop-replace the JsonForms component with the ControlledJsonForms component without changing any of your code.