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

Support useFormStatus in progressively-enhanced forms #29019

Merged
merged 2 commits into from
May 9, 2024

Commits on May 9, 2024

  1. Fix: Coerce form submitter action prop

    When handling form action functions, we should coerce the submitter
    formAction prop using the same logic as ReactDOMComponent before
    deciding whether it should override the action on the <form>.
    
    Before this fix, if the submitter's `formAction` prop was a symbol or
    a boolean, it would block the form's action function from firing, but
    the correct behavior is that symbols and booleans should be treated as
    if they were null/empty, because that's how we treat those values when
    setting DOM properties.
    acdlite committed May 9, 2024
    Configuration menu
    Copy the full SHA
    3081f94 View commit details
    Browse the repository at this point in the history
  2. useFormStatus in progressively-enhanced forms

    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:
    
    ```js
    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 committed May 9, 2024
    Configuration menu
    Copy the full SHA
    a23e517 View commit details
    Browse the repository at this point in the history