DEV Community

Makoto Tsuga
Makoto Tsuga

Posted on

Form Actions in React 19

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.

Here, I implement the following the system to explain form actions.

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

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)


"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>
  );
}
Enter fullscreen mode Exit fullscreen mode

server(/app/api/submit/route.ts)

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 });
}
Enter fullscreen mode Exit fullscreen mode

Result

Image description

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)

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

Result

Image description
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.

Top comments (0)