Next.js Server Actions実行後に何かしたいときの3パターン
Next.jsのServer Actions表記はいつServer Functionsに変わるんだろう?と気になっている@zaruです、こんにちは。今回はNext.jsでServer Actions実行後になにかしたいときの実装を3パターン紹介します。
パターン1: Server Actionsで後処理
最初はもうシンプルにServer Actionsの関数内で実行します。今回はリダイレクトを実行する例にします。バックエンド側で実行できるような後処理であれば原則Server Actions内で制御するのが良いと思います。
import { submit } from "./action";
export default function Page() {
return (
<form action={submit}>
<button type="submit">Submit</button>
</form>
);
}
"use server";
import { redirect } from "next/navigation";
export async function submit(formData: FormData) {
// いろいろ処理した後にリダイレクトさせる
redirect("/");
}
パターン2: ClientComponentで後処理
ここからはClientComponent側の後処理になります。Server Actions関数をラップする関数を用意し、その中で後処理を実装します。あとは通常のServer Actionsと同様に action
属性に渡せばOKです。
"use client";
import { submit } from "@/app/after_submit/handle_action/action";
import { useRouter } from "next/navigation";
export default function Page() {
const router = useRouter();
// Server Actionsの関数をラップする関数を作って呼び出す
const handleSubmit = async (formData: FormData) => {
await submit(formData);
// 処理完了後にリダイレクトさせる
router.push("/");
};
return (
<form action={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
"use server";
export async function submit(formData: FormData) {
// Server Actionsの必要な処理
}
パターン3: useActionStateで後処理
最後に useActionState
もしくは useFormState
を使った例です。パターン2と同様にServer Actions関数をラップします。違いはそのラップした関数を useActionState
もしくは useFormState
にわたすようにする点と引数を変更することです。
"use client";
import { submit } from "@/app/after_submit/use_action_state/action";
import { useRouter } from "next/navigation";
import { useActionState } from "react";
export default function Page() {
const router = useRouter();
// Server Actionsの関数をラップし、useActionStateに合った関数を作って呼び出す
const handleSubmit = async (_prevState: object, formData: FormData) => {
await submit();
// 処理完了後にリダイレクトさせる
router.push("/");
return {};
};
const [_state, action] = useActionState(handleSubmit, {});
return (
<form action={action}>
<input type={"text"} name={"name"} />
<button type="submit">Submit</button>
</form>
);
}
"use server";
export async function submit(formData: FormData) {
// Server Actionsの必要な処理
}
after
おまけ: Next.js v15からは after
という機能が登場しています。これを使うと、LayoutやPage、Server Actionsなどのレンダリング後あるいは実行後に after
で定義した処理を実行することができます。今回の例で出したリダイレクトは用途に合いませんが、ロギングやレポート送信などで活用することができます。
Server Actionsで after
を使った例です。
"use server";
import { redirect } from "next/navigation";
import { after } from "next/server";
export async function submit(formData: FormData) {
after(() => {
console.log("Server Actionsが実行されたよ!!!");
});
redirect("/");
}
after
の処理はレンダリングをブロックしないので、使い所としては利用者に影響を与えず何らかの処理をしたい時ですね。
Discussion