Enhance form documentation for form default reset behavior#8512
Enhance form documentation for form default reset behavior#8512MaxwellCohen wants to merge 12 commits into
Conversation
Size changesDetails📦 Next.js Bundle Analysis for react-devThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
|
Going to dig a bit into the current behavior of this, so might take some time to review! Thank you! |
…ction` prop and its behavior: - including the handling of `FormData`, - the necessity of `name` attributes, - the advantages of using a function over a URL. - removed redundant information about `e.preventDefault()` for the `action` prop.
| Give each input a `name` attribute so its value is included in `FormData`. You can use [uncontrolled](/reference/react-dom/components/input#reading-the-input-values-when-submitting-a-form) inputs instead of controlled `value`/`onChange` pairs, and you don't need an `onSubmit` handler or `e.preventDefault()`. | ||
|
|
||
| Pass a function to the `action` prop of form to run the function when the form is submitted. [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) will be passed to the function as an argument so you can access the data submitted by the form. This differs from the conventional [HTML action](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action), which only accepts URLs. Unlike `onSubmit`, an `action` runs in a [Transition](/reference/react/useTransition) and calling `e.preventDefault()` isn't needed. After the `action` function succeeds, all uncontrolled field elements in the form are reset. | ||
| This extends the [HTML `action` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action), which only accepts a URL, to also accept a function. Because the form stays a native HTML form, it can be submitted before JavaScript loads; with a [Server Function](/reference/rsc/server-functions), it works without JavaScript enabled. |
There was a problem hiding this comment.
ecause the form stays a native HTML form, it can be submitted before JavaScript loads; with a [Server Function](/reference/rsc/server-functions), it works without JavaScript enabled
this part is a bit unclear and hard to parse!
There was a problem hiding this comment.
Great point. When I read it 3 times last week, it seemed so clear ;) now it is not
udpate in b341728
There was a problem hiding this comment.
I feel you on that 😂
|
|
||
| * Runs the submission function in a [Transition](/reference/react/useTransition). | ||
| * Tracks pending state so child components can read it with [`useFormStatus`](/reference/react-dom/hooks/useFormStatus). | ||
| * Sends thrown errors to the nearest error boundary. |
There was a problem hiding this comment.
Not sure if "sends" is the right terminology for this 🤔
| * Runs the submission function in a [Transition](/reference/react/useTransition). | ||
| * Tracks pending state so child components can read it with [`useFormStatus`](/reference/react-dom/hooks/useFormStatus). | ||
| * Sends thrown errors to the nearest error boundary. | ||
| * Works with [`useActionState`](/reference/react/useActionState) and [`useOptimistic`](/reference/react/useOptimistic) for form state and optimistic UI. |
There was a problem hiding this comment.
This bullet seems out of place in its framing, since the intro to the list is When you pass a function to action, React: but here "works" is not answering that question!
| ### Display a pending state during form submission {/*display-a-pending-state-during-form-submission*/} | ||
| ### Preserving form values after submission {/*preserve-form-values-after-submission*/} | ||
|
|
||
| The browser clears a form's input state on submit. A URL `action` follows this same behavior. React does the same when `action` is a function, so your form works consistently before and after JavaScript loads. |
There was a problem hiding this comment.
this paragraph reads a little strange, and the behavior was explained better above!
|
|
||
| </Sandpack> | ||
|
|
||
| Because you call the action manually from `onSubmit`, [`useFormStatus`](/reference/react-dom/hooks/useFormStatus) won't report its pending state. Read `isPending` from the same [`useTransition`](/reference/react/useTransition) call instead. |
There was a problem hiding this comment.
Hm, i thought useFormStatus worked regardless, also with onSubmit?
There was a problem hiding this comment.
yep, I got just using onSubmit without action confused
| When a user taps a specific button, the form is submitted, and a corresponding action, defined by that button's attributes and action, is executed. For instance, a form might submit an article for review by default but have a separate button with `formAction` set to save the article as a draft. | ||
| When a button without `formAction` submits the form, React calls the form's `action`. When a button with `formAction` submits the form, React calls that button's action instead. For example, the form below publishes an article by default, but its **Save draft** button stores the current content without publishing it. | ||
|
|
||
| In this example the draft is held in state, so the saved content stays in the textarea after you submit it. In a real app you would persist the draft on the server. Pass a [Server Function](/reference/rsc/server-functions) (a function marked with [`'use server'`](/reference/rsc/use-server)) to `formAction` to save the draft from the server, optionally combined with [`useActionState`](/reference/react/useActionState) to track its pending state and result. |
There was a problem hiding this comment.
(a function marked with 'use server')
is this a common pattern in the docs?
There was a problem hiding this comment.
Most of the examples are called out in the code update it in code, so moving to code and using useActionState
947c926
There was a problem hiding this comment.
To be clear, sorry if this was too biref, i was wondering about the usage of the () inline linking of in that way!!
There was a problem hiding this comment.
But i think its better the way you did it regardless
| function EditForm() { | ||
| // The action returns { submitted: formData, error } on failure | ||
| const [state, formAction] = useActionState(submitForm, {}); | ||
| const values = state.submitted ?? new FormData(); |
There was a problem hiding this comment.
Why do we need a seperate variable for values? Is this pattern better than returning the values from the useActionState function?
https://aurorascharff.no/posts/handling-form-validation-errors-and-resets-with-useactionstate/
https://www.robinwieruch.de/react-server-action-reset-form/
There was a problem hiding this comment.
Good point, I forgot about optional chaining (one of my favorite JS features when working on making the examples)
7288a0d to
08359a5
Compare
08359a5 to
947c926
Compare
Summary
Documents React’s default form-reset behavior when using the function
action/formActionprops, and explains how to preserve field values when you don’t want that reset. Applying @rickhanlonii's feedback from #7795 and building off of work @aurorascharff recentlly did.actionprop section, and a new Troubleshooting entry (“Why does my form reset when I use an action?”). React resets uncontrolled fields after a successful action, matching browser<form action="...">behavior (including before JS loads).e.preventDefault()inonSubmit, then run the action manually insideuseTransitionwhile keeping theactionprop for progressive enhancement.requestFormResetfromreact-dom, and returning submittedFormDatafrom server actions to restore values viadefaultValue(withuseActionState).key/defaultValuekeep textarea content after “Save draft.”Closes #8397
Alternative to #7795 and #8465