サーバー側で実行される非同期関数をクライアントから直接呼べる仕組み。フォーム送信やミューテーション処理に使う。
// ── Server Action の基本 ─────────────────────────────────
// 'use server' を書いた関数は「サーバーで実行される関数」
// → API ルートを作らずにフォーム送信やDB操作ができる
'use server';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
// ── フォーム送信で使う例 ──────────────────────────────
async function createPost(formData: FormData) {
// formData.get() でフォームの入力値を取得
const title = formData.get('title') as string;
const content = formData.get('content') as string;
// バリデーション
if (!title || title.length < 3) {
throw new Error('タイトルは3文字以上必要です');
}
// DBに保存(サーバーサイドで実行される)
await db.posts.create({ data: { title, content } });
// キャッシュを更新して /posts の表示を最新にする
revalidatePath('/posts');
// 投稿一覧へリダイレクト
redirect('/posts');
}
// ── フォームコンポーネントでの使い方 ─────────────────
// action に Server Action を直接渡す
export function CreatePostForm() {
return (
<form action={createPost}>
<input name="title" placeholder="タイトル" required />
<textarea name="content" placeholder="内容" />
<button type="submit">投稿する</button>
</form>
);
}
// ── ボタンクリックでServer Actionを呼ぶ(Client Component)
"use client"; // ← 実際はファイル先頭
export function DeleteButton({ postId }: { postId: number }) {
const handleDelete = async () => {
await deletePost(postId); // Server Action を呼ぶ
};
return <button onClick={handleDelete}>削除</button>;
}Server Actionsはフォームのaction属性に直接渡せるため、JavaScriptが無効な環境(プログレッシブエンハンスメント)でも動作する。