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が生成しており、誤りが含まれる場合があります。正確な情報は公式ドキュメント等でご確認ください。