Skip to content

Commit 6ef844b

Browse files
authored
useFormState reference fixes (#6383)
* Add useFormState reference * Matt's suggestions for useFormState reference * Incorporated PR feedback for useFormState
1 parent 5e40d13 commit 6ef844b

File tree

2 files changed

+34
-33
lines changed

2 files changed

+34
-33
lines changed

src/content/reference/react-dom/hooks/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "React DOM Hooks"
2+
title: "Built-in React DOM Hooks"
33
---
44

55
<Intro>
@@ -21,7 +21,7 @@ Form Hooks are currently only available in React's canary and experimental chann
2121
*Forms* let you create interactive controls for submitting information. To manage forms in your components, use one of these Hooks:
2222

2323
* [`useFormStatus`](/reference/react-dom/hooks/useFormStatus) allows you to make updates to the UI based on the status of the a form.
24-
* `useFormState` allows you to manage state inside a form.
24+
* [`useFormState`](/reference/react-dom/hooks/useFormState) allows you to manage state inside a form.
2525

2626
```js
2727
function Form({ action }) {
@@ -46,3 +46,4 @@ function Button() {
4646
);
4747
}
4848
```
49+

src/content/reference/react-dom/hooks/useFormState.md

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ canary: true
55

66
<Canary>
77

8-
The `useFormState` Hook is currently only available in React's canary and experimental channels. Learn more about [React's release channels here](/community/versioning-policy#all-release-channels). In addition, you need to use a framework that supports React Server Components to get the full benefit of `useFormState`.
8+
The `useFormState` Hook is currently only available in React's canary and experimental channels. Learn more about [release channels here](/community/versioning-policy#all-release-channels). In addition, you need to use a framework that supports [React Server Components](/reference/react/use-client) to get the full benefit of `useFormState`.
99

1010
</Canary>
1111

1212
<Intro>
1313

14-
`useFormState` is a Hook that allows you to read the return value of the form action after a form is submitted.
14+
`useFormState` is a Hook that allows you to update state based on the result of a form action.
1515

1616
```js
17-
const [state, formAction] = useFormState(action, initalState);
17+
const [state, formAction] = useFormState(fn, initialState);
1818
```
1919

2020
</Intro>
@@ -25,24 +25,25 @@ const [state, formAction] = useFormState(action, initalState);
2525

2626
## Reference {/*reference*/}
2727

28-
### `useFormState()` {/*useformstate*/}
29-
30-
In the context of React Server Components, an *action* is a function that may be [executed when a form is submitted](/reference/react-dom/components/form). You can execute actions on the server or on the client.
28+
### `useFormState(action, initialState)` {/*useformstate*/}
3129

3230
{/* TODO T164397693: link to actions documentation once it exists */}
3331

34-
Call `useFormState` at the top level of your component to see the return value of an action after submitting a form. You pass `useFormState` an existing action as well as an initial state, and it returns a new action that you use when submitting your form, along with the latest form state.
32+
Call `useFormState` 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 `useFormState` 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.
3533

3634
```js
37-
function AddToCart({itemID}) {
38-
const [message, formAction] = useFormState(addToCartAction, null);
35+
import { useFormState } from "react-dom";
36+
37+
async function increment(previousState, formData) {
38+
return previousState + 1;
39+
}
40+
41+
function StatefulForm({}) {
42+
const [state, formAction] = useFormState(increment, 0);
3943
return (
40-
<form action={formAction}>
41-
<input type="hidden" name="itemID" value={itemID} />
42-
<button type="submit" label="Add to cart" />
43-
<p>
44-
{message}
45-
</p>
44+
<form>
45+
{state}
46+
<button formAction={formAction}>Increment</button>
4647
</form>
4748
)
4849
}
@@ -56,23 +57,22 @@ If used with a server action, `useFormState` allows the server's response from s
5657

5758
#### Parameters {/*parameters*/}
5859

59-
* `action`: The action to be performed when the form is submitted. When the action is called, it will receive the previous state of the form (initially the `initialState` that you pass, subsequently its previous return value) as its initial argument, followed by the arguments that an action normally receives.
60-
* `initialState`: The value you want the state to be initially. It can be any serializable value. This argument is ignored after the form is first submitted.
60+
* `fn`: The function to be called when the form is submitted or button pressed. When the function is called, it will receive the previous state of the form (initially the `initialState` that you pass, subsequently its previous return value) as its initial argument, followed by the arguments that a form action normally receives.
61+
* `initialState`: The value you want the state to be initially. It can be any serializable value. This argument is ignored after the action is first invoked.
6162

6263
{/* TODO T164397693: link to serializable values docs once it exists */}
6364

64-
6565
#### Returns {/*returns*/}
6666

6767
`useFormState` returns an array with exactly two values:
6868

69-
1. The current state. During the first render, it will match the `initialState` you have passed. After the form is submitted, it will match the value returned by the action.
70-
2. A new action that you can pass as the `action` prop to your `form` component.
69+
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.
70+
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.
7171

7272
#### Caveats {/*caveats*/}
7373

74-
* When used with a framework that supports React Server Components, `useFormState` lets you make forms interactive before JavaScript has executed on the client. When used without Server Components, there is no advantage to using it over component local state.
75-
* The action passed to `useFormState` receives an extra argument, the previous or initial state state, as its first argument. This makes its signature different than if it were used directly without `useFormState`.
74+
* When used with a framework that supports React Server Components, `useFormState` lets you make forms interactive before JavaScript has executed on the client. When used without Server Components, it is equivalent to component local state.
75+
* The function passed to `useFormState` receives an extra argument, the previous or initial state, as its first argument. This makes its signature different than if it were used directly as a form action without using `useFormState`.
7676

7777
---
7878

@@ -102,7 +102,7 @@ function MyComponent() {
102102
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.
103103
2. A <CodeStep step={2}>new action</CodeStep> that you pass to `<form>` as its `action` prop.
104104

105-
When the form is submitted, the <CodeStep step={3}>action</CodeStep> that you provided will be called. Its return value will become the new <CodeStep step={1}>current state</CodeStep> of the form.
105+
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.
106106

107107
The <CodeStep step={3}>action</CodeStep> that you provide will also receive a new first argument, namely the <CodeStep step={1}>current state</CodeStep> of the form. The first time the form is submitted, this will be the <CodeStep step={4}>initial state</CodeStep> you provided, while with subsequent submissions, it will be the return value from the last time the action was called. The rest of the arguments are the same as if `useFormState` had not been used
108108

@@ -141,8 +141,8 @@ function AddToCartForm({itemID, itemTitle}) {
141141
export default function App() {
142142
return (
143143
<>
144-
<AddToCartForm itemID="1" itemTitle="Javascript: The Definitive Guide" />
145-
<AddToCartForm itemID="2" itemTitle="Javascript: The Good Parts" />
144+
<AddToCartForm itemID="1" itemTitle="JavaScript: The Definitive Guide" />
145+
<AddToCartForm itemID="2" itemTitle="JavaScript: The Good Parts" />
146146
</>
147147
)
148148
}
@@ -176,8 +176,8 @@ form button {
176176
```json package.json hidden
177177
{
178178
"dependencies": {
179-
"react": "experimental",
180-
"react-dom": "experimental",
179+
"react": "canary",
180+
"react-dom": "canary",
181181
"react-scripts": "^5.0.0"
182182
},
183183
"main": "/index.js",
@@ -223,8 +223,8 @@ function AddToCartForm({itemID, itemTitle}) {
223223
export default function App() {
224224
return (
225225
<>
226-
<AddToCartForm itemID="1" itemTitle="Javascript: The Definitive Guide" />
227-
<AddToCartForm itemID="2" itemTitle="Javascript: The Good Parts" />
226+
<AddToCartForm itemID="1" itemTitle="JavaScript: The Definitive Guide" />
227+
<AddToCartForm itemID="2" itemTitle="JavaScript: The Good Parts" />
228228
</>
229229
)
230230
}
@@ -264,8 +264,8 @@ form button {
264264
```json package.json hidden
265265
{
266266
"dependencies": {
267-
"react": "experimental",
268-
"react-dom": "experimental",
267+
"react": "canary",
268+
"react-dom": "canary",
269269
"react-scripts": "^5.0.0"
270270
},
271271
"main": "/index.js",

0 commit comments

Comments
 (0)