← inaro.devAI駆動開発 学習ツール
中級

Server Actions

なぜ学ぶか: 「フォームの送信のためにAPIを作ってfetchして…」— その面倒を消すのがServer Actionsです。フォームからサーバーの関数を「直接」呼べます。例を見てください。

まずはこの例を見てみましょう

// ===== actions.ts(サーバーで実行される関数)=====
"use server";

export async function createPost(formData: FormData) {
  const title = formData.get("title");
  // ここでデータベースに保存する(サーバーなので安全)
}

// ===== page.tsx(フォームから直接呼ぶ)=====
<form action={createPost}>
  <input name="title" />
  <button type="submit">投稿する</button>
</form>

formのactionに「サーバーの関数」を直接渡しています。fetchもAPI定義も不要です。

Server Action=フォームから直接呼べるサーバー関数

例のように"use server"を付けた関数をformのactionに渡すと、送信時にサーバーで実行されます。

'use client'とは別物

'use client'は「このファイルはブラウザ行き」、'use server'は「この関数はサーバーで実行」。似ていますが対象が違います。

データを変えたらrevalidatePath

保存した後にrevalidatePath("/posts")を呼んで「このページを作り直して」と伝えます。忘れると「保存したのに画面が古い」となります(次のキャッシュのトピックで詳しく)。

レビュー観点:入力の検証

ユーザー入力を受ける以上、保存前の検証(zod)が必須です。AIが素通しで保存していたら指摘します。

コード例

// ===== app/posts/actions.ts(サーバーで実行される関数)=====
"use server";
import { revalidatePath } from "next/cache";

export async function createPost(formData: FormData) {
  const title = formData.get("title") as string;
  // 本来はここで zod 検証 → DB へ保存
  console.log("サーバーで保存:", title);
  revalidatePath("/posts"); // 忘れると画面が古いまま
}

// ===== app/posts/new/page.tsx(フォームから直接呼ぶ)=====
import { createPost } from "../actions";

export default function NewPostPage() {
  return (
    <form action={createPost}>
      <input name="title" placeholder="タイトル" />
      <button type="submit">投稿する</button>
    </form>
  );
}

fetchもAPI定義も出てこないのに、送信内容がサーバーへ届いています。これがServer Actionsの便利さです。

ステップ 1 / 2

※ カリキュラムの内容はAIが生成しており、誤りが含まれる場合があります。正確な情報は公式ドキュメント等でご確認ください。