コース一覧
Next.jsフルスタック:サーバー・データ取得・API
Server Actionsの触り

Next.jsフルスタック:サーバー・データ取得・API

Server ComponentsとClient Components、use client、サーバーfetch、asyncコンポーネント、動的ルート、params、notFound、キャッシュ、Route Handler、GET・POST API、Server Actions、フォームを扱う全24レッスンのフルスタックコースです。fleamaの商品取得と出品機能をNext.js内へ実装します。

1
Server / Client Components
01. サーバーで動く部品10分
02. Server Components15分
03. use clientの宣言15分
04. どちらに置くか15分
05. 境界をまたぐ合成15分
06. 境界の設計15分
07. つくる - 部品の仕分け20分
08. 第4章クイズ15分
2
データ取得と動的ルート
01. サーバーでfetch15分
02. asyncコンポーネント15分
03. 動的ルート15分
04. paramsを受け取る15分
05. notFoundで404にする15分
06. キャッシュのきほん10分
07. 検索をサーバーで15分
08. つくる - サーバー取得化20分
09. 第5章クイズ15分
3
API Routesとフォーム
01. Route Handler15分
02. GET APIを作る15分
03. POST APIを作る15分
04. Server Actionsの触り15分
05. フォーム実装15分
06. つくる - 受け口の完成20分
07. 第6章クイズ15分

Server Actionsの触り

API を作らずに直接呼ぶ

fetch を書かずにサーバーへ渡す

ここまでの作りでは、送る側と受け取る側の2つを書いてきました。ページで fetch("/api/items", { method: "POST" }) と書き、app/api/items/route.ts で POST を書く。あいだをつなぐのは URL です。

Next.js には、この2つを1つにまとめる書き方があります。Server Actions と呼びます。サーバーで動かしたい関数の先頭に "use server" と書き、その関数をフォームに直接渡します。

TypeScript

"use server"; export async function createItem(formData: FormData) { const title = String(formData.get("title") ?? ""); return { message: title + " を受け付けました" }; }

TypeScript (JSX)

import { createItem } from "./actions"; export default function SellPage() { return ( <form action={createItem}> <input name="title" /> <button type="submit">出品する</button> </form> ); }

URL がどこにも出てきません。fetch も書いていません。それでもボタンを押すと createItem はサーバー側で動きます。あいだの通信は Next.js が用意します。

引数は FormData で届く

form の action に関数を渡すと、その関数は FormData を受け取ります。name を付けた入力が、そのまま formData.get("title") で取り出せます。JSON にして送る手間がありません。ただし取り出した値は文字なので、数として使うなら Number(...) を通します。

route.ts との使い分け

Server Actions が出たからといって route.ts が要らなくなるわけではありません。目安は下記のとおりです。

  • 自分のアプリのフォームから送るだけなら Server Actions が短い
  • スマホアプリや他社のサービスなど、外から決まった URL で叩かれるなら route.ts

この章で route.ts を先にやったのは、こちらが土台だからです。URL があって、メソッドがあって、状態コードを返す。Server Actions はその往復を隠してくれているだけで、裏で起きていることは同じです。

演習

このプレビューには本物のサーバーがないので、action に渡す代わりにページ側から直接呼びます。書き方そのものは本物と同じです。

ヒント

取り出しは formData.get("title") です。文字で届くので価格は Number(...) を通します

返すのは { message: ... } の形です。ページ側は result.message を画面に出します

文をつなぐときは title + " を " + price + " 円で受け付けました" です

layout.tsx
actions.ts
page.tsx
プレビュー

できているか

  • 先頭の use server が残っている
  • 商品名が空だと断られる
  • そろっていれば受け付ける
  • FormData から値を取り出している
エディタを読み込んでいます