Learning
Next.js

Server Actions & API-k

Server Actions, useFormStatus, useActionState és Route Handlers áttekintése.

Next.js – Server Actions & API-k

A teljes Next.js jegyzet 8–9. fejezetének kivonata.


Mi az a Server Action?

  • Szerver oldalon futó aszinkron függvény,
  • közvetlenül hívható a kliensről (pl. <form action={action}>),
  • nem kell hozzá külön REST endpoint.
// app/actions.ts
"use server";

import { db } from '@/lib/db';
import { revalidatePath } from 'next/cache';

export async function createPost(formData: FormData) {
  const title = formData.get('title') as string;
  const content = formData.get('content') as string;

  await db.insert(postsTable).values({ title, content });
  revalidatePath('/blog');
}

Használat form‑ban:

// app/blog/new/page.tsx
import { createPost } from '@/app/actions';

export default function NewPostPage() {
  return (
    <form action={createPost}>
      <input type="text" name="title" required />
      <textarea name="content" required />
      <button type="submit">Közzétesz</button>
    </form>
  );
}

useFormStatus – pending állapot

"use client";
import { useFormStatus } from 'react-dom';

function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? 'Küldés...' : 'Küldés'}
    </button>
  );
}

Fontos: a SubmitButton‑t a <form> belsejébe kell tenni.


useActionState – eredmény & hiba kezelése

// actions.ts
"use server";

export async function createPost(prevState: any, formData: FormData) {
  const title = formData.get('title') as string;
  if (!title) return { error: 'A cím kötelező!' };
  // ... mentés
  return { success: true };
}
"use client";
import { useActionState } from 'react';
import { createPost } from './actions';

export default function NewPostForm() {
  const [state, formAction, isPending] = useActionState(createPost, null);

  return (
    <form action={formAction}>
      <input name="title" />
      {state?.error && <p style={{ color: 'red' }}>{state.error}</p>}
      <button disabled={isPending}>{isPending ? 'Küldés...' : 'Küldés'}</button>
    </form>
  );
}

Mikor jó a Server Action?

Használd, ha:

  • form beküldés (login, regisztráció, CRUD),
  • cache érvénytelenítés (revalidatePath, revalidateTag),
  • redirect form után (redirect).

Kerüld, ha:

  • külső rendszereknek is kell hívni az endpointot → inkább Route Handler,
  • nagyon sok helyről, sokféleképpen kell hívni → REST vagy RPC API jobban átlátható.

Route Handlers – API endpointok

Struktúra:

app/
└── api/
    └── users/
        └── route.ts   → /api/users
// app/api/users/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  const users = await db.select().from(usersTable);
  return NextResponse.json(users);
}

export async function POST(request: Request) {
  const body = await request.json();
  const newUser = await db.insert(usersTable).values(body).returning();
  return NextResponse.json(newUser[0], { status: 201 });
}

Dinamikus route:

app/api/products/[id]/route.ts   → /api/products/123
import { NextRequest, NextResponse } from 'next/server';

export async function GET(
  req: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const { id } = await params;
  const product = await getProductById(id);
  if (!product) {
    return NextResponse.json({ error: 'Nem található' }, { status: 404 });
  }
  return NextResponse.json(product);
}

Server Actions vs Route Handlers

HelyzetAjánlott
Benti form, nincs külső kliensServer Action
Nyilvános API‑t kell adni más rendszereknekRoute Handler
Egyszerű mutáció + cache frissítésServer Action
Komplett CRUD, külső kliensekkelRoute Handlers (REST/RPC)

Összefoglalás

  • Server Action: a legegyszerűbb út formok kezelésére Next.js App Router‑ben.
  • useFormStatus és useActionState kényelmes UI‑t ad pending / hiba / siker állapothoz.
  • Route Handlers: klasszikus HTTP API endpointok, ha a világ felé is publikálnod kell az API‑t.

On this page