Skip to content

Commit 2b2d0f2

Browse files
useActionState pending example (#6989)
Co-authored-by: Sebastian "Sebbie" Silbermann <[email protected]>
1 parent bb38630 commit 2b2d0f2

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

src/content/reference/react/useActionState.md

+12-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ In earlier React Canary versions, this API was part of React DOM and called `use
2020
`useActionState` is a Hook that allows you to update state based on the result of a form action.
2121

2222
```js
23-
const [state, formAction] = useActionState(fn, initialState, permalink?);
23+
const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);
2424
```
2525
2626
</Intro>
@@ -35,7 +35,7 @@ const [state, formAction] = useActionState(fn, initialState, permalink?);
3535
3636
{/* TODO T164397693: link to actions documentation once it exists */}
3737
38-
Call `useActionState` at the top level of your component to create component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useActionState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state. The latest form state is also passed to the function that you provided.
38+
Call `useActionState` at the top level of your component to create component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useActionState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state and whether the Action is still pending. The latest form state is also passed to the function that you provided.
3939
4040
```js
4141
import { useActionState } from "react";
@@ -71,10 +71,11 @@ If used with a Server Action, `useActionState` allows the server's response from
7171
7272
#### Returns {/*returns*/}
7373
74-
`useActionState` returns an array with exactly two values:
74+
`useActionState` returns an array with the following values:
7575
7676
1. The current state. During the first render, it will match the `initialState` you have passed. After the action is invoked, it will match the value returned by the action.
7777
2. A new action that you can pass as the `action` prop to your `form` component or `formAction` prop to any `button` component within the form.
78+
3. The `isPending` flag that tells you whether there is a pending Transition.
7879
7980
#### Caveats {/*caveats*/}
8081
@@ -104,10 +105,11 @@ function MyComponent() {
104105
}
105106
```
106107
107-
`useActionState` returns an array with exactly two items:
108+
`useActionState` returns an array with the following items:
108109
109110
1. The <CodeStep step={1}>current state</CodeStep> of the form, which is initially set to the <CodeStep step={4}>initial state</CodeStep> you provided, and after the form is submitted is set to the return value of the <CodeStep step={3}>action</CodeStep> you provided.
110111
2. A <CodeStep step={2}>new action</CodeStep> that you pass to `<form>` as its `action` prop.
112+
3. A <CodeStep step={1}>pending state</CodeStep> that you can utilise whilst your action is processing.
111113
112114
When the form is submitted, the <CodeStep step={3}>action</CodeStep> function that you provided will be called. Its return value will become the new <CodeStep step={1}>current state</CodeStep> of the form.
113115
@@ -133,13 +135,13 @@ import { useActionState, useState } from "react";
133135
import { addToCart } from "./actions.js";
134136

135137
function AddToCartForm({itemID, itemTitle}) {
136-
const [message, formAction] = useActionState(addToCart, null);
138+
const [message, formAction, isPending] = useActionState(addToCart, null);
137139
return (
138140
<form action={formAction}>
139141
<h2>{itemTitle}</h2>
140142
<input type="hidden" name="itemID" value={itemID} />
141143
<button type="submit">Add to Cart</button>
142-
{message}
144+
{isPending ? "Loading..." : message}
143145
</form>
144146
);
145147
}
@@ -162,6 +164,10 @@ export async function addToCart(prevState, queryData) {
162164
if (itemID === "1") {
163165
return "Added to cart";
164166
} else {
167+
// Add a fake delay to make waiting noticeable.
168+
await new Promise(resolve => {
169+
setTimeout(resolve, 2000);
170+
});
165171
return "Couldn't add to cart: the item is sold out.";
166172
}
167173
}

0 commit comments

Comments
 (0)