actions.ts:
"use server";
import { z } from "zod";
const SignUpSchema = z.object({
username: z.string(),
password: z
.string()
.min(8, { message: "Be at least 8 characters long" })
.regex(/[a-zA-Z]/, { message: "Contain at least one letter." })
.regex(/[0-9]/, { message: "Contain at least one number." })
.regex(/[^a-zA-Z0-9]/, {
message: "Contain at least one special character.",
})
.trim(),
});
export type SignUpActionState = {
username?: string;
password?: string;
errors?: {
username?: string[];
password?: string[];
};
};
export async function signUp(
_prevState: SignUpActionState,
form: FormData
): Promise<signupactionstate> {
const username = form.get("username") as string;
const password = form.get("password") as string;
const validatedFields = SignUpSchema.safeParse({
username,
password,
});
if (!validatedFields.success) {
return {
username,
password,
errors: validatedFields.error.flatten().fieldErrors,
};
}
// process validated form inputs here
return { username, password };
}
</signupactionstate>
useActionState 也傳回一個 isPending 屬性(範例),指示伺服器操作的 Promise 是否仍在解析。
參考 isPending 暫時停用表單元素,例如提交按鈕,以防止使用者在正在進行的操作完成之前快速連續多次點擊它。
useActionState 與 useFormAction 和 useFormStatus
如果您熟悉 useFormAction 和 useFormStatus,您會發現 useActionState 非常相似。
本質上,它結合了兩個鉤子的功能,並被重新命名以反映伺服器操作不僅僅適用於表單(您還可以將 useActionState 與按鈕和其他元素一起使用。)
請記住,useFormStatus 從 Next.js 15 開始已被棄用,因此您應該繼續匯入 useActionState。