Skip to content

Commit e426aa5

Browse files
committed
Reorder sections for better progressive disclosure of ideas
1 parent 5245923 commit e426aa5

1 file changed

Lines changed: 49 additions & 54 deletions

File tree

  • src/content/reference/react-dom/components

src/content/reference/react-dom/components/form.md

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,14 @@ To create interactive controls for submitting information, render the [built-in
5151

5252
### Handle form submission with an event handler {/*handle-form-submission-with-an-event-handler*/}
5353

54-
Pass a function to the `onSubmit` event handler to run code when the form is submitted. By default, the browser sends the form data to the current URL and refreshes the page, so call [`e.preventDefault()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault) to override that behavior.
54+
Pass a function to the `onSubmit` event handler to run code when the form is submitted. By default, the browser sends the form data to the current URL and refreshes the page. Call [`e.preventDefault()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault) in your handler to override that behavior. Read the submitted data with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).
5555

56-
This example reads the submitted values with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData), which collects every field by its `name`. This keeps the inputs [uncontrolled](/reference/react-dom/components/input#reading-the-input-values-when-submitting-a-form). If you instead [control an input with state](/reference/react-dom/components/input#controlling-an-input-with-a-state-variable), read from that state on submit rather than from `FormData`.
5756

5857
<Sandpack>
5958

6059
```js src/App.js
6160
export default function Search() {
6261
function handleSubmit(e) {
63-
// Prevent the default browser behavior
64-
// of reloading the page and resetting the form
65-
e.preventDefault();
66-
67-
// Read the form data
6862
const form = e.target;
6963
const formData = new FormData(form);
7064
const query = formData.get("query");
@@ -111,6 +105,54 @@ export default function Search() {
111105

112106
</Sandpack>
113107

108+
109+
### Handle form submission with a Server Function {/*handle-form-submission-with-a-server-function*/}
110+
111+
Render a `<form>` with an input and submit button. Pass a Server Function (a function marked with [`'use server'`](/reference/rsc/use-server)) to the `action` prop of form to run the function when the form is submitted.
112+
113+
Passing a Server Function to `<form action>` allow users to submit forms without JavaScript enabled or before the code has loaded. This is beneficial to users who have a slow connection, device, or have JavaScript disabled and is similar to the way forms work when a URL is passed to the `action` prop.
114+
115+
You can use hidden form fields to provide data to the `<form>`'s action. The Server Function will be called with the hidden form field data as an instance of [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).
116+
117+
```jsx
118+
import { updateCart } from './lib.js';
119+
120+
function AddToCart({productId}) {
121+
async function addToCart(formData) {
122+
'use server'
123+
const productId = formData.get('productId')
124+
await updateCart(productId)
125+
}
126+
return (
127+
<form action={addToCart}>
128+
<input type="hidden" name="productId" value={productId} />
129+
<button type="submit">Add to Cart</button>
130+
</form>
131+
132+
);
133+
}
134+
```
135+
136+
In lieu of using hidden form fields to provide data to the `<form>`'s action, you can call the <CodeStep step={1}>`bind`</CodeStep> method to supply it with extra arguments. This will bind a new argument (<CodeStep step={2}>`productId`</CodeStep>) to the function in addition to the <CodeStep step={3}>`formData`</CodeStep> that is passed as an argument to the function.
137+
138+
```jsx [[1, 8, "bind"], [2,8, "productId"], [2,4, "productId"], [3,4, "formData"]]
139+
import { updateCart } from './lib.js';
140+
141+
function AddToCart({productId}) {
142+
async function addToCart(productId, formData) {
143+
"use server";
144+
await updateCart(productId)
145+
}
146+
const addProductToCart = addToCart.bind(null, productId);
147+
return (
148+
<form action={addProductToCart}>
149+
<button type="submit">Add to Cart</button>
150+
</form>
151+
);
152+
}
153+
```
154+
155+
When `<form>` is rendered by a [Server Component](/reference/rsc/use-client), and a [Server Function](/reference/rsc/server-functions) is passed to the `<form>`'s `action` prop, the form is [progressively enhanced](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement).
114156
### Preserve form values after submission {/*preserve-form-values-after-submission*/}
115157

116158
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.
@@ -190,53 +232,6 @@ Return the original `FormData` object rather than a new one so React can restore
190232
191233
</DeepDive>
192234
193-
### Handle form submission with a Server Function {/*handle-form-submission-with-a-server-function*/}
194-
195-
Render a `<form>` with an input and submit button. Pass a Server Function (a function marked with [`'use server'`](/reference/rsc/use-server)) to the `action` prop of form to run the function when the form is submitted.
196-
197-
Passing a Server Function to `<form action>` allow users to submit forms without JavaScript enabled or before the code has loaded. This is beneficial to users who have a slow connection, device, or have JavaScript disabled and is similar to the way forms work when a URL is passed to the `action` prop.
198-
199-
You can use hidden form fields to provide data to the `<form>`'s action. The Server Function will be called with the hidden form field data as an instance of [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).
200-
201-
```jsx
202-
import { updateCart } from './lib.js';
203-
204-
function AddToCart({productId}) {
205-
async function addToCart(formData) {
206-
'use server'
207-
const productId = formData.get('productId')
208-
await updateCart(productId)
209-
}
210-
return (
211-
<form action={addToCart}>
212-
<input type="hidden" name="productId" value={productId} />
213-
<button type="submit">Add to Cart</button>
214-
</form>
215-
216-
);
217-
}
218-
```
219-
220-
In lieu of using hidden form fields to provide data to the `<form>`'s action, you can call the <CodeStep step={1}>`bind`</CodeStep> method to supply it with extra arguments. This will bind a new argument (<CodeStep step={2}>`productId`</CodeStep>) to the function in addition to the <CodeStep step={3}>`formData`</CodeStep> that is passed as an argument to the function.
221-
222-
```jsx [[1, 8, "bind"], [2,8, "productId"], [2,4, "productId"], [3,4, "formData"]]
223-
import { updateCart } from './lib.js';
224-
225-
function AddToCart({productId}) {
226-
async function addToCart(productId, formData) {
227-
"use server";
228-
await updateCart(productId)
229-
}
230-
const addProductToCart = addToCart.bind(null, productId);
231-
return (
232-
<form action={addProductToCart}>
233-
<button type="submit">Add to Cart</button>
234-
</form>
235-
);
236-
}
237-
```
238-
239-
When `<form>` is rendered by a [Server Component](/reference/rsc/use-client), and a [Server Function](/reference/rsc/server-functions) is passed to the `<form>`'s `action` prop, the form is [progressively enhanced](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement).
240235
241236
### Display a pending state during form submission {/*display-a-pending-state-during-form-submission*/}
242237
To display a pending state when a form is being submitted, you can call the `useFormStatus` Hook in a component rendered in a `<form>` and read the `pending` property returned.

0 commit comments

Comments
 (0)