Server Actions คืออะไร
ไอเดียในหนึ่งประโยค
หัวข้อที่มีชื่อว่า “ไอเดียในหนึ่งประโยค”Server Action คือ async function ที่ mark ด้วย directive "use server" และรันบน server เท่านั้น เราเรียก action ตรง ๆ จาก <form> หรือจาก Client Component ได้เลยโดยไม่ต้องเขียน API route
The "use server" directive
หัวข้อที่มีชื่อว่า “The "use server" directive”เรา mark function ให้เป็น Server Action ได้สองแบบ แบบแรกใส่ "use server" ไว้บนสุดของ inline async function ภายใน Server Component แบบที่สองใส่ 'use server' ไว้บนสุดของทั้ง module file แล้วทุก export ในไฟล์นั้นจะกลายเป็น action
// app/page.tsx — an inline Server Action inside a Server Componentexport default function Page() { async function createTodo(formData: FormData) { 'use server' const title = String(formData.get('title')) await db.todo.create({ data: { title } }) }
return ( <form action={createTodo}> <input name="title" /> <button type="submit">Add</button> </form> )}A shared actions module
หัวข้อที่มีชื่อว่า “A shared actions module”เมื่อหลาย component ต้องใช้ action เดียวกัน ให้ย้าย action ไปไว้ในไฟล์เฉพาะ ใส่ 'use server' หนึ่งครั้งบนสุด แล้วทุก export จะกลายเป็น action ที่เรียกได้ วิธีนี้รวม logic ของ mutation ไว้ที่เดียว และให้ Client Component import ไปใช้ได้
// app/actions.ts — every export here is a Server Action'use server'
export async function createTodo(formData: FormData) { const title = String(formData.get('title')) await db.todo.create({ data: { title } })}
export async function deleteTodo(id: string) { await db.todo.delete({ where: { id } })}Calling from a form and from a Client Component
หัวข้อที่มีชื่อว่า “Calling from a form and from a Client Component”เราต่อ Server Action เข้ากับ form ตรง ๆ ด้วย <form action={createTodo}> แล้ว Next.js จะ post ข้อมูล form ไปที่ action บน server หรือจะ import action เข้าไปใน Client Component แล้วเรียกเหมือน function ปกติก็ได้ Next.js จะแปลง call นั้นเป็น network request ให้เอง
// app/todo-button.tsx — calling an action from a Client Component'use client'
import { deleteTodo } from './actions'
export function DeleteButton({ id }: { id: string }) { return <button onClick={() => deleteTodo(id)}>Delete</button>}How it differs from a Route Handler
หัวข้อที่มีชื่อว่า “How it differs from a Route Handler”Route Handler ใน route.ts คือ URL สาธารณะที่เราออกแบบ ต่อ และ fetch เอง ส่วน Server Action คือ function ที่เราเรียกตรง ๆ Next.js สร้าง endpoint และ network call ให้ และรองรับ progressive enhancement ผ่าน form เลือก Route Handler เมื่อต้องการ public API หรือ webhook จริง ๆ และเลือก Server Action สำหรับ flow ของ form และ mutation ภายใน app ของเราเอง
graph LR A["form or Client Component"] -->|"calls action"| B["Next.js generated endpoint"] B -->|"runs on server only"| C["Server Action function"] C -->|"reads or writes"| D["Database"]