Skip to content

Commit 5380f95

Browse files
committed
chore(website): update docs
1 parent 2af5619 commit 5380f95

File tree

5 files changed

+25
-80
lines changed

5 files changed

+25
-80
lines changed

website/docs/execute-actions/hooks/usestateaction.md

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,73 +16,10 @@ You can access the documentation for the deprecated `useStateAction()` hook in t
1616

1717
### From v8 onwards
1818

19-
The `useStateAction()` hook has been deprecated in favor of the [`useActionState`](https://react.dev/reference/react/useActionState) hook from React, which was used under the hood. This is because the usage of `useStateAction`, while adding useful features, prevented progressive enhancement from working, since it wrapped the `useActionState` hook with additional functionality that only worked with JavaScript enabled.
19+
The `useStateAction()` hook has been deprecated in favor of the [`useActionState()`](https://react.dev/reference/react/useActionState) hook from React, which was used anyway under the hood. This is because the `useStateAction()` hook, while adding useful features, prevented progressive enhancement from working, since it wrapped the `useActionState()` hook with additional functionality that only worked with JavaScript enabled.
2020

2121
Note that you can also use "stateless" actions with forms, as described in [this section](/docs/recipes/form-actions#stateless-form-actions).
2222

2323
### Example
2424

25-
1. Define a new stateful action called `statefulAction`, that takes a name as input and returns the name you just passed, as well as the previous one (if any).
26-
27-
Note two important things:
28-
1. We're defining an action that will be used as a Form Action, so here we use the [`zod-form-data`](https://www.npmjs.com/package/zod-form-data) library to generate the input validation schema;
29-
2. We use [`stateAction()`](/docs/define-actions/instance-methods#action--stateaction) instance method to define the action. You **must** use this method, because `useActionState()` hook requires `prevResult` to be the first argument of the Server Action function. Using this method also allows you to access the previous action result in `serverCodeFn`, via the `prevResult` property in the second argument of the function:
30-
31-
```typescript title=src/app/stateful-action.ts
32-
"use server";
33-
34-
import { actionClient } from "@/lib/safe-action";
35-
import { z } from "zod";
36-
import { zfd } from "zod-form-data";
37-
38-
const inputSchema = zfd.formData({
39-
name: zfd.text(z.string().min(1).max(20)),
40-
});
41-
42-
export const statefulAction = actionClient
43-
.metadata({ actionName: "statefulAction" })
44-
.inputSchema(inputSchema)
45-
// Note that we need to explicitly give a type to `stateAction` here,
46-
// for its return object. This is because TypeScript can't infer the
47-
// return type of the function and then "pass it" to the second argument
48-
// of the server code function (`prevResult`). If you don't need to
49-
// access `prevResult`, though, you can omit the type here, since it
50-
// will be inferred just like with `action` method.
51-
// highlight-start
52-
.stateAction<{
53-
prevName?: string;
54-
newName: string;
55-
}>(async ({ parsedInput, metadata }, { prevResult }) => {
56-
await new Promise((res) => setTimeout(res, 1000));
57-
58-
return {
59-
prevName: prevResult.data?.newName,
60-
newName: parsedInput.name,
61-
};
62-
});
63-
// highlight-end
64-
```
65-
66-
2. Then, in your Client Component, you can define a form like this one, and pass the action we just defined to the form `action` prop:
67-
68-
```tsx
69-
"use client";
70-
71-
import { useActionState } from "react";
72-
import { statefulAction } from "./action";
73-
74-
export function TestForm() {
75-
// Optionally pass initial state as the second argument.
76-
// An empty object is required, even if you don't pass any initial state,
77-
// since it has to match the type of the action's return object.
78-
// highlight-next-line
79-
const [state, action, isPending] = useActionState(statefulAction, {});
80-
81-
return {
82-
// highlight-next-line
83-
<form action={action}>
84-
...
85-
</form>
86-
}
87-
}
88-
```
25+
Take a look at [this section](/docs/recipes/form-actions#stateful-form-actions) of the documentation for an example of how to use the `useActionState()` hook to create a stateful action.

website/docs/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ This is a basic client, without any options or middleware functions. If you want
3737

3838
### 2. Define a new action
3939

40-
This is how a safe action is created. Providing a validation input schema to the function via [`inputSchema()`](/docs/define-actions/instance-methods#inputSchema), we're sure that data that comes in is type safe and validated.
40+
This is how a safe action is created. Providing a validation input schema to the function via [`inputSchema()`](/docs/define-actions/instance-methods#inputschema), we're sure that data that comes in is type safe and validated.
4141
The [`action()`](/docs/define-actions/instance-methods#action--stateaction) method lets you define what happens on the server when the action is called from client, via an async function that receives the parsed input and context as arguments. In short, this is your _server code_. **It never runs on the client.
4242

4343
In this documentation, we'll use the Zod library to define our validation logic, but feel free to use any other library that implements the [Standard Schema](https://github.com/standard-schema/standard-schema) specification.

website/docs/migrations/v6-to-v7.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ By default, next-safe-action v7 returns validation errors in an object of the sa
137137

138138
As already said above, by default version 7 now returns validation errors in the same format of the Zod's [`format`](https://zod.dev/ERROR_HANDLING?id=formatting-errors) method.
139139

140-
This is customizable by using the `handleValidationErrorsShape`/`handleBindArgsValidationErrorsShape` optional functions in `schema`/`bindArgsSchemas` methods. Check out [this page](/docs/define-actions/validation-errors#customize-validation-errors-format) for more information. For example, if you need to work with flattened errors for a specific action, next-safe-action conveniently provides two functions to do that: [`flattenValidationErrors` and `flattenBindArgsValidationErrors`](/docs/define-actions/validation-errors#flattenvalidationerrors-and-flattenbindargsvalidationerrors-utility-functions).
140+
This is customizable by using the `handleValidationErrorsShape`/`handleBindArgsValidationErrorsShape` optional functions in `schema`/`bindArgsSchemas` methods. Check out [this page](/docs/define-actions/validation-errors#customize-validation-errors-format) for more information. For example, if you need to work with flattened errors for a specific action, next-safe-action conveniently provides two functions to do that: [`flattenValidationErrors` and `flattenBindArgsValidationErrors`](/docs/define-actions/validation-errors#formatvalidationerrors-utility-function).
141141

142142
### [Allow calling `action` method without `schema`](https://github.com/TheEdoRan/next-safe-action/issues/107)
143143

website/docs/migrations/v7-to-v8.md

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ The behavior when using functions from `next/navigation` was very unclear and co
4141

4242
This behavior has been changed in v8. Now, when you're using functions imported from `next/navigation` in an action:
4343
- the hooks `status` value will be `"hasNavigated"` instead of `"hasSucceeded"`;
44-
- a new `onNavigation` callback will be triggered, both for actions and hooks, instead of `onSuccess`. This callback receives a `navigationKind` value, that indicates the type of navigation that occurred;
44+
- a new `onNavigation()` callback will be triggered, both for actions and hooks, instead of `onSuccess()`. This callback receives a `navigationKind` value, that indicates the type of navigation that occurred;
4545
- the `success` property of the middleware result will now be `false`, instead of `true`, if a navigation function was called in a middleware function or in the action's server code function.
4646

4747
```typescript
@@ -90,7 +90,7 @@ const result = await boundAction(input);
9090

9191
### ⚠️✨ Removal of deprecated `executeOnMount` hook option
9292

93-
The deprecated `executeOnMount` hook functionality has been removed in v8. Server Actions should be used only for mutations, so it doesn't make sense to execute them on mount. Or at least, it shouldn't be a common case and, above all, a library job. If you still need to do it, just use `useEffect` to trigger the execution, however you want.
93+
The deprecated `executeOnMount` hook functionality has been removed in v8. Server Actions should be used only for mutations, so it doesn't make sense to execute them on mount. Or at least, it shouldn't be a common case and, above all, a library job. If you still need to do it, just use `useEffect()` to trigger the execution, however you want.
9494

9595
### ✨ Type-checked metadata
9696

@@ -102,7 +102,7 @@ This is a big improvement in type safety over v7. Metadata is now statically typ
102102

103103
### ✨ Custom thrown validation error messages
104104

105-
The `throwValidationErrors` option now accepts both a boolean (just like in v7) and an object with a `overrideErrorMessage` function, that allows you to customize the thrown `Error` message on the client side.
105+
The `throwValidationErrors` option now accepts both a boolean (just like in v7) and an object with a `overrideErrorMessage()` function, that allows you to customize the thrown `Error` message on the client side.
106106

107107
```typescript
108108
import { throwValidationErrors, overrideErrorMessage } from "next-safe-action";
@@ -149,9 +149,9 @@ const { data } = await action(input);
149149

150150
### 🔄 `schema` method renamed to `inputSchema`
151151

152-
The library, since version 7.8.0, supports both input and output validation, respectively using the `schema` and `outputSchema` methods. In v8, the `schema` method has been renamed to `inputSchema` to better reflect its purpose, and avoid potential confusion.
152+
The library, since version 7.8.0, supports both input and output validation, respectively using the `schema()` and `outputSchema()` methods. In v8, the `schema()` method has been renamed to `inputSchema()` to better reflect its purpose, and avoid potential confusion.
153153

154-
The `schema` method is deprecated and will be removed in a future version, but it's still available for backward compatibility. It's now just an alias for `inputSchema`:
154+
The `schema()` method is deprecated and will be removed in a future version, but it's still available for backward compatibility. It's now just an alias for `inputSchema()`:
155155

156156
```typescript title="v7"
157157
actionClient.schema(/* ... */)
@@ -162,16 +162,15 @@ actionClient.inputSchema(/* ... */)
162162
```
163163

164164
:::info UPDATE EXISTING ACTIONS
165-
To update your actions, you can just use the search and replace feature of your editor to replace all occurrences of `.schema` with `.inputSchema`.
165+
To update your actions, you can just use the search and replace feature of your editor to replace all occurrences of `.schema()` with `.inputSchema()`.
166166
:::
167167

168168

169169
### 🔄 Deprecation of `useStateAction` hook
170170

171-
The `useStateAction` hook has been deprecated. It's always been kind of a hack to begin with, and it doesn't support progressive enhancement, since it tries to do what the `useAction` and `useOptimisticAction` hooks do.
171+
The `useStateAction()` hook has been deprecated. It's always been kind of a hack to begin with, and it doesn't support progressive enhancement, since it tries to do what the `useAction()` and `useOptimisticAction()` hooks do.
172172

173-
So, from now one, the recommended way to use stateful actions is to do it with the React's built in `useActionState` hook, as explained in [this section](#) of the documentation.
174-
#### TODO: add link
173+
So, from now one, the recommended way to use stateful actions is to do it with the React's built in `useActionState()` hook, as explained in [this section](/docs/recipes/form-actions#stateful-form-actions) of the documentation.
175174

176175
## Requirements
177176

website/docs/recipes/form-actions.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ Note that if you want or need to use _stateful_ actions:
8484

8585
Here's an example of a stateful action, using the `useActionState()` hook:
8686

87+
1. Define a new stateful action called `statefulFormAction()`, that takes a name as input and returns the name you just passed, as well as the previous one (if any).
88+
8789
```typescript title="stateful-form-action.ts"
8890
"use server";
8991

@@ -95,13 +97,15 @@ const inputSchema = zfd.formData({
9597
name: zfd.text(z.string().min(1).max(20)),
9698
});
9799

98-
// Note that we need to explicitly give a type to `stateAction` here, for its return object.
99-
// This is because TypeScript can't infer the return type of the function and then "pass it" to
100-
// the second argument of the server code function (`prevResult`). If you don't need to access `prevResult`,
101-
// though, you can omit the type here, since it will be inferred just like with `action` method.
102100
export const statefulFormAction = action
103101
.inputSchema(inputSchema)
104102
// highlight-start
103+
// Note that we need to explicitly give a type to `stateAction` here,
104+
// for its return object. This is because TypeScript can't infer the
105+
// return type of the function and then "pass it" to the second argument
106+
// of the server code function (`prevResult`). If you don't need to
107+
// access `prevResult`, though, you can omit the type here, since it
108+
// will be inferred just like with `action` method.
105109
.stateAction<{
106110
prevName?: string;
107111
newName: string;
@@ -114,13 +118,18 @@ export const statefulFormAction = action
114118
// highlight-end
115119
```
116120

121+
2. Then, in your Client Component, you can define a form like this one, and pass the action we just defined to the form `action` prop:
122+
117123
```tsx title="stateful-form.tsx"
118124
"use client";
119125

120126
import { useActionState } from "react";
121127
import { statefulFormAction } from "./stateful-form-action";
122128

123129
export default function StatefulForm() {
130+
// Optionally pass initial state as the second argument.
131+
// An empty object is required, even if you don't pass any initial state,
132+
// since it has to match the type of the action's return object.
124133
// highlight-start
125134
const [state, action, isPending] = useActionState(
126135
statefulFormAction,

0 commit comments

Comments
 (0)