Skip to content

Commit 0946026

Browse files
authored
docs: explain useFormStatus with custom form actions
Closes #8682. Document when `useFormStatus().pending` is set for a `preventDefault()` submit handler that starts a Transition in the same event, and add a runnable example for a custom form action. The example also notes that this pattern does not reset the form automatically. Validation: `yarn check-all` and `git diff --check` pass locally. The initial draft was prepared with AI assistance and reviewed against the React DOM tests and issue details.
1 parent 8c68ae8 commit 0946026

1 file changed

Lines changed: 58 additions & 1 deletion

File tree

‎src/content/reference/react-dom/hooks/useFormStatus.md‎

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ In the above example, `Submit` uses this information to disable `<button>` press
5454

5555
A `status` object with the following properties:
5656

57-
* `pending`: A boolean. If `true`, this means the parent `<form>` is pending submission. Otherwise, `false`.
57+
* `pending`: A boolean. If `true`, this means the parent `<form>` is pending submission. Otherwise, `false`. `pending` is also `true` while a Transition started from a `submit` event handler is pending, as long as the handler calls `event.preventDefault()` and starts the Transition in the same event.
5858

5959
* `data`: An object implementing the [`FormData interface`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) that contains the data the parent `<form>` is submitting. If there is no active submission or no parent `<form>`, it will be `null`.
6060

@@ -112,6 +112,63 @@ export async function submitForm(query) {
112112
```
113113
</Sandpack>
114114

115+
### Display a pending state with a custom form action {/*display-a-pending-state-with-a-custom-form-action*/}
116+
117+
If you need to handle form submission in an `onSubmit` event handler instead of passing a function to the `<form action>` prop, call `event.preventDefault()` and start a Transition in the same event handler. A component inside the form can then use `useFormStatus` to read the pending state while the action is running.
118+
119+
<Sandpack>
120+
121+
```js src/App.js
122+
import { startTransition } from 'react';
123+
import { useFormStatus } from 'react-dom';
124+
import { submitForm } from './submitForm.js';
125+
126+
function SubmitButton() {
127+
const { pending } = useFormStatus();
128+
return (
129+
<button type="submit" disabled={pending}>
130+
{pending ? 'Submitting...' : 'Submit'}
131+
</button>
132+
);
133+
}
134+
135+
function Form({ submitAction }) {
136+
function handleSubmit(event) {
137+
event.preventDefault();
138+
const formData = new FormData(event.currentTarget);
139+
startTransition(async () => {
140+
await submitAction(formData);
141+
});
142+
}
143+
144+
return (
145+
<form onSubmit={handleSubmit}>
146+
<input name="query" />
147+
<SubmitButton />
148+
</form>
149+
);
150+
}
151+
152+
export default function App() {
153+
async function submitAction(formData) {
154+
await submitForm(formData);
155+
}
156+
157+
return <Form submitAction={submitAction} />;
158+
}
159+
```
160+
161+
```js src/submitForm.js hidden
162+
export async function submitForm(formData) {
163+
await new Promise((resolve) => setTimeout(resolve, 1000));
164+
}
165+
```
166+
167+
</Sandpack>
168+
169+
Unlike a function passed to the `<form action>` prop, handling submission this way does not automatically reset the form.
170+
171+
115172
<Pitfall>
116173

117174
##### `useFormStatus` will not return status information for a `<form>` rendered in the same component. {/*useformstatus-will-not-return-status-information-for-a-form-rendered-in-the-same-component*/}

0 commit comments

Comments
 (0)