Stop 08 · ReactTopics · 9/20

Forms

Part of the Frontend Developer Roadmap

In short

Login, sign-up, search, checkout: forms are everywhere. React 19 makes them simpler by letting a form call your function directly with all its data.

Handling user input in React — reading values, tracking state per field, validating and submitting — often the most state-heavy part of a UI.

The jaadu mascot slides a filled paper slip across a bank counter to a cashier.

Think of it like this

A bank deposit slip

You fill in your name, account number and amount, then hand the whole slip to the cashier at once. You don't shout each field separately. A form action works the same way: the browser bundles every field into a FormData slip and hands it to your function.

Watch it happen

A form action, start to finish

You
Form
React
subscribe()

type + Subscribe

1/6You type an email and press Subscribe.

The big ideas

What you need to know

name is what matters

Every input needs a name attribute. That's the key you read it by, like formData.get("email").

onSubmit or action

Classic way: onSubmit with e.preventDefault(). React 19 way: pass a function to the form's action prop.

Show the pending state

useActionState gives you the result and an isPending flag, so you can disable the button while it saves.

Validate twice

Use required, type="email" and minLength for quick checks in the browser, and always validate again on the server.

See it in code

Walk through the code

tsx
1import { useActionState } from "react";2async function subscribe(_prev: string, formData: FormData) {3  const email = formData.get("email");4  await new Promise((r) => setTimeout(r, 1000)); // pretend API call5  return "Subscribed " + email;6}7export default function Newsletter() {8  const [message, formAction, isPending] = useActionState(subscribe, "");9  return (10    <form action={formAction}>11      <input name="email" type="email" required />12      <button disabled={isPending}>{isPending ? "Saving..." : "Subscribe"}</button>13      <p>{message}</p>14    </form>15  );16}

1/4The action gets the previous state and FormData, and reads the field by its name.

React calls subscribe with the form's data and puts its return value in message. Once the action finishes, React resets the form's uncontrolled fields for you.

Save yourself the pain

Common mistakes

Oops

Using onSubmit and forgetting e.preventDefault().

Do this instead

Without it the browser reloads the page. Call it first, or use the action prop, which handles this for you.

Oops

Inputs with no name attribute.

Do this instead

FormData only collects fields that have a name. No name, no value.

Your mission

Sign-up form with a spinner

~25 min

Quick check

A form has <input type="email" /> with no name. What does formData.get("email") return?

Go deeper

  1. 1Build a form with multiple fields tracked in a single state object.
  2. 2Practice basic validation and displaying inline error messages.
  3. 3Try a form library (React Hook Form) once you understand the manual approach.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge