Server Actions
Server Action Form Submission
This example was originally created as one of several examples I wrote for a post about Using Server Actions with Next JS. See that post for a more detailed explanation of the concepts here.
Forms can be submitted directly to the server using Server Actions. Here's a basic form that shows how to do that with the useFormState
hook (see warning below on whether to use that or useActionState
):
Live Demo
Here's a live inline demo of this form in action. If you submit it without entering any text, its server action will return an error message. If you enter some text, it will return a success message with an ID for the device you created.
Under the covers, React creates an API endpoint for us, and then provides its own wrapper calls and data structures on both the request and response cycles, leaving us to focus solely on our UI and business logic. It uses our createDeviceAction
to automatically create an endpoint, and if you submit the form you will see a POST request being made to whatever url the form is on.
Use client components for forms
If you plan to use a form with a Server Action, it needs to be marked as a client component by adding 'use client'
to the top of the file. RSCs can render forms just fine, but if you want to use the useFormState
hook, your code needs to be running on the client.
The Server Action that this form submits to is defined in a separate file. This runs on the server, so add a 'use server' directive at the top of the file:
Authentication doesn't happen automagically
This is a very simple example, but in a real-world application you would likely want to add some kind of authentication to your server actions. These server action endpoints are as wide open as any other, so you need to reason about them in the exact same way when it comes to authentication and authorization.
The createDeviceAction
function receives the form data and returns an object with a status
and message
property. The code here is simulating a database mutation and doing some basic validation. If the form data is valid, it also returns a device
object. You don't need to use status
and message
in your form - you can send anything you like back.
Finally, you can render the form in your app (in this case we're rendering the page that contains the form as an RSC):
One nice thing about this is that the Enter key works on your keyboard without any extra code. This is because the form is a real form, and the submit button is a real submit button. The formAction hook is doing the work of intercepting the form submission and calling the server action instead of the default form submission. It feels more like the old school web.
useFormState vs useActionState
At the moment (mid-2024), you might need to use useActionState
or useFormState
, depending on which version of React you are using. useActionState
is only available in React 19 canary, while useFormState
is available in React 18, though in 18 it's on 'react-dom'.
Clear as mud? Take a look at this GH issue for clues on which to use based on your version of React/react-dom/Next.js.