React: Calling handleChange/addItem/removeItems in an async callback

I’m noticing some interesting behavior in a custom renderer. I’m trying to create a custom file upload renderer using react-dropzone to allow users to upload one or more files. When I call either addItem (using ArrayControlProps) or handleChange (using ControlProps) before an async API request, an item gets added to the array as expected. But when I specify it after awaiting the API request, the change doesn’t take place. More specifically, what I see in the logs is that the file is briefly added, then somehow overridden. I need to wait for the API response so I can add an item to the array with the proper data (e.g. unique ID, metadata, etc).

Working Example:

async def uploadFile(files: File[]) {
  for (const file of files) {
    addItem(path, { id: "dummy", filename: file.name })();

    await apiRequest(); // My API request here
  }
}

Broken Example:

async def uploadFile(files: File[]) {
  for (const file of files) {
    const response = await apiRequest(); // My API request here

    addItem(path, { id: response.file.id, filename: response.file.name })();
  }
}

Hi @pranav-kunapuli,

I think we run into issues here with JSON Forms hybrid approach to support “controlled” and “uncontrolled” behavior at the same time.

You can check whether that is the case by stabilizing the data prop. Just hand over the initial data as a stable object and do not update it with the new data from JSON Forms, like this:

const [runtimeData, setRuntimeData] = useState({});
const [initialData] = useState(runtimeData);
// ...
<JsonForms {...otherProps} data={initialData} onChange={(event) => setRuntimeData(event.data)} />

If the problem goes away, then this is the culprit.

If you never need to update the data from outside JSON Forms then you can use this workaround to solve the issue. If you need to adapt it during the lifetime of the form, then using the new middleware functionality you can convert JSON Forms into a fully controllable component and the issue will be solved too.

Can you verify whether stabilizing the data works for you?