react icon indicating copy to clipboard operation
react copied to clipboard

Support useFormStatus in progressively-enhanced forms

Open acdlite opened this issue 1 month ago • 4 comments

Before this change, useFormStatus is only activated if a form is submitted by an action function (either <form action={actionFn}> or <button formAction={actionFn}>).

After this change, useFormStatus will also be activated if you call startTransition(actionFn) inside a submit event handler that is preventDefault-ed.

This is the last missing piece for implementing a custom action prop that is progressively enhanced using onSubmit while maintaining the same behavior as built-in form actions.

Here's the basic recipe for implementing a progressively-enhanced form action. This would typically be implemented in your UI component library, not regular application code:

import {requestFormReset} from 'react-dom';

// To implement progressive enhancement, pass both a form action *and* a
// submit event handler. The action is used for submissions that happen
// before hydration, and the submit handler is used for submissions that
// happen after.
<form
  action={action}
  onSubmit={(event) => {
    // After hydration, we upgrade the form with additional client-
    // only behavior.
    event.preventDefault();

    // Manually dispatch the action.
    startTransition(async () => {
      // (Optional) Reset any uncontrolled inputs once the action is
      // complete, like built-in form actions do.
      requestFormReset(event.target);

      // ...Do extra action-y stuff in here, like setting a custom
      // optimistic state...

      // Call the user-provided action
      const formData = new FormData(event.target);
      await action(formData);
    });
  }}
/>

acdlite avatar May 08 '24 02:05 acdlite