Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update authentication docs to use useActionState #72503

Merged
merged 3 commits into from
Nov 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The examples on this page walk through basic username and password auth for educ

### Sign-up and login functionality

You can use the [`<form>`](https://react.dev/reference/react-dom/components/form) element with React's [Server Actions](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) and `useFormState` to capture user credentials, validate form fields, and call your Authentication Provider's API or database.
You can use the [`<form>`](https://react.dev/reference/react-dom/components/form) element with React's [Server Actions](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) and `useActionState` to capture user credentials, validate form fields, and call your Authentication Provider's API or database.

Since Server Actions always execute on the server, they provide a secure environment for handling authentication logic.

Expand Down Expand Up @@ -200,16 +200,16 @@ export async function signup(state, formData) {
}
```

Back in your `<SignupForm />`, you can use React's `useFormState` hook to display validation errors while the form is submitting:
Back in your `<SignupForm />`, you can use React's `useActionState` hook to display validation errors while the form is submitting:

```tsx filename="app/ui/signup-form.tsx" switcher highlight={7,15,21,27-39}
```tsx filename="app/ui/signup-form.tsx" switcher highlight={7,15,21,27-36}
'use client'

import { useFormState, useFormStatus } from 'react-dom'
import { signup } from '@/app/actions/auth'
import { useActionState } from 'react'

export function SignupForm() {
const [state, action] = useFormState(signup, undefined)
export default function SignupForm() {
const [state, action, pending] = useActionState(signup, undefined)

return (
<form action={action}>
Expand Down Expand Up @@ -239,42 +239,34 @@ export function SignupForm() {
</ul>
</div>
)}
<SubmitButton />
<button disabled={pending} type="submit">
Sign Up
</button>
</form>
)
}

function SubmitButton() {
const { pending } = useFormStatus()

return (
<button disabled={pending} type="submit">
Sign Up
</button>
)
}
```

```jsx filename="app/ui/signup-form.js" switcher highlight={7,15,21,27-39}
```jsx filename="app/ui/signup-form.js" switcher highlight={7,15,21,27-36}
'use client'

import { useFormState, useFormStatus } from 'react-dom'
import { signup } from '@/app/actions/auth'
import { useActionState } from 'react'

export function SignupForm() {
const [state, action] = useFormState(signup, undefined)
export default function SignupForm() {
const [state, action, pending] = useActionState(signup, undefined)

return (
<form action={action}>
<div>
<label htmlFor="name">Name</label>
<input id="name" name="name" placeholder="John Doe" />
<input id="name" name="name" placeholder="Name" />
</div>
{state?.errors?.name && <p>{state.errors.name}</p>}

<div>
<label htmlFor="email">Email</label>
<input id="email" name="email" placeholder="[email protected]" />
<input id="email" name="email" placeholder="Email" />
</div>
{state?.errors?.email && <p>{state.errors.email}</p>}

Expand All @@ -292,25 +284,16 @@ export function SignupForm() {
</ul>
</div>
)}
<SubmitButton />
<button disabled={pending} type="submit">
Sign Up
</button>
</form>
)
}

function SubmitButton() {
const { pending } = useFormStatus()

return (
<button disabled={pending} type="submit">
Sign Up
</button>
)
}
```

> **Good to know:**
>
> - These examples use React's `useFormState` hook, which is bundled with the Next.js App Router. If you are using React 19, use `useActionState` instead. See the [React docs](https://react.dev/reference/react/useActionState) for more information.
> - In React 19, `useFormStatus` includes additional keys on the returned object, like data, method, and action. If you are not using React 19, only the `pending` key is available.
> - In React 19, `useActionState` also includes a `pending` key on the returned state.
> - Before mutating data, you should always ensure a user is also authorized to perform the action. See [Authentication and Authorization](#authorization).
Expand Down
Loading