Component state updates after an async upload query are not immediately reflected in the UI, leading to stale data rendering unless manual debouncing is introduced

  1. My goal:

    I want to upload a file from a File Button component to my custom backend API endpoint using multipart/form-data, and immediately reflect the uploaded media in the UI without introducing artificial delays.


    Issue:

    When triggering the upload query immediately after selecting a file:

    • On the first click, the API is hit but the backend does not properly receive the file (appears incomplete or empty).

    • On the second click, the upload succeeds β€” but it uploads the previously selected file, not the currently selected one.

    This suggests the File Button’s value is not fully resolved before the query executes, resulting in stale or delayed state.

    The behavior only stabilizes if I introduce a manual debounce (~100ms) before triggering the upload query.

    Without the debounce, uploads are inconsistent and unreliable.


    Steps I've taken to troubleshoot:

    • Verified the backend endpoint independently (works correctly outside Retool).

    • Confirmed multipart/form-data is correctly configured.

    • Logged addMediaButton.value before triggering the query.

    • Confirmed that the file object appears valid in console logs.

    • Tested with and without uploadToRetoolStorage.

    • Confirmed that introducing a setTimeout delay resolves the issue.

    • Confirmed that the issue is reproducible consistently without debouncing.

    Example workaround:

    setTimeout(() => {
      uploadFile.trigger();
    }, 100);
    

    With this delay, the upload works correctly on first attempt.


    Additional info:

    • Retool Cloud

    • File Button component (single selection)

    • Custom API endpoint (not using Retool Storage as final destination)

    • Upload triggered manually via button click

    • Using query success handler to update UI state