All posts
·#Next.js#React

Server Actions Quietly Killed My useState

Notes from porting an AI Job Copilot form to Server Actions — fewer hooks, simpler error states, real progressive enhancement.

I rebuilt the job-tracker form in the App Router using Server Actions and useFormState. The diff was almost entirely deletions.

"use client";
import { useFormState } from "react-dom";
import { createApplication } from "./actions";

export function NewApplicationForm() {
  const [state, action] = useFormState(createApplication, { error: null });
  return (
    <form action={action} className="space-y-3">
      <input name="company" required />
      <input name="role" required />
      {state.error && <p className="text-destructive">{state.error}</p>}
      <button>Save</button>
    </form>
  );
}

No fetch wrapper, no isSubmitting, no toast plumbing — and it still works with JS disabled.