Form Actions in React 19
Tags: webdev, react, node, react19
Published: 2024-05-13 21:28:52

Hello everyone. I would like to write about form actions updated in React 19, which is one of new features.

## What is Form Action?
Form Actions is feature to implement easily the process of the server side when submitting in the form.

- Synchronous and asynchronous functions can be easily implemented by using action which is props in form.

- It is possible to pass form information to the function as an argument.

- The status of the form (pending, etc.) can be obtained by using useFormStatus which is new hook in react 19.

<u>Here, I  implement the following the system to explain form actions.</u>

> When you click the register button on a form, I would like to  output the name entered in input to the debug console log as a server-side process.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijso5askqkeyjpajag6t.png)



## Older use of the form
In the previous way.....

- The useState and onChange were used to get the contents of the input.
- To execute server-side processing, you need to specify an endpoint like /api/submit and use the fetch function to POST data.
- It was necessary to prepare a separate file, such as /app/api/submit/route.ts, to handle the processing on the server-side.








**client(/app/page.tsx)**

```react

"use client";
import React, { useState } from "react";

export default function Home() {
  const [name, setName] = useState("");
  const submit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    fetch("/api/submit", {
      method: "POST",
      body: JSON.stringify({ message: name }),
    });
  };
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setName(e.target.value);
  };

  return (
    <form className="" onSubmit={submit}>
      <div>
        <label>Name:</label>
        <input type="text" value={name} onChange={handleInputChange} />
      </div>
      <button className="border border-black">Resister</button>
    </form>
  );
}
```
**server(/app/api/submit/route.ts)**

```react
import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest) {
  const { message } = (await req.json()) as { message?: string };
  console.log(message);
  return NextResponse.json("ok", { status: 200 });
}
```
**Result**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xqauv0v88u8q0hyr9tg.png)


when click the button, I can see the input text I entered in the debug console.


## New use of the form

- You can specify a function in a Form action and execute it.
- It is necessary to write "use server" inside function.
- You can pass an argument called formData that holds form information to the specified function.
- The contents of input can be obtained by using the "formData.get method". At that time, pass the name of the input you want to obtain as an argument.

**client(/app/page.tsx)**
```react
export default function Home() {
  const formAction = async (formData: FormData) => {
    "use server";
    console.log(formData.get("firstName"));
  };

  return (
    <form action={formAction}>
      <div>
        <label>Name:</label>
        <input type="text" name="firstName" />
      </div>
      <button className="border border-black">Resister</button>
    </form>
  );
}
```
**Result**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bsp6ghgaa2kqyulqg3ei.png)
when click the button, I can see the input text I entered in the debug console.



By using the form action, we do not need to create the endpoints and use the useState. 


I explained a new hook, useFormStatus, that allows you to obtain the status (pending, etc.) in  Form actions. If you want to know how to use it, [please read the another article.](https://dev.to/makoto0825/useformstatus-in-react-19-3khh)