Mục lục

Server Actions: Cuộc cách mạng Mutations

Tạm biệt API Routes thủ công. Tìm hiểu cách Server Actions giúp bạn xử lý Form, cập nhật Database và revalidate dữ liệu ngay tại Client với type-safety tuyệt đối.

Server Actions là các hàm JavaScript chạy trực tiếp trên Server nhưng có thể được gọi từ Client (Form, Button, Transition).

1. Tại sao lãng phí thời gian tạo API Routes?

Trước đây:

  1. Tạo app/api/post/route.ts (POST).
  2. Viết logic xử lý.
  3. Ở Client dùng fetch('/api/post', { method: 'POST', body: ... }).
  4. Check types thủ công.

Bây giờ:

  1. Viết 1 function gắn use server.
  2. Truyền vào prop action của <form>. Xong.

2. Cách triển khai chuẩn mực

tsx:
// app/actions.ts
'use server';

import { revalidatePath } from 'next/cache';

export async function createPost(formData: FormData) {
  const title = formData.get('title');
  
  // 1. Lưu vào Database
  await db.post.create({ data: { title } });
  
  // 2. Clear cache để Page cập nhật dữ liệu mới ngay lập tức
  revalidatePath('/posts');
  
  return { success: true };
}
tsx:
// app/posts/NewPostForm.tsx
'use client';

import { createPost } from '../actions';

export function NewPostForm() {
  return (
    <form action={createPost}>
      <input name="title" required />
      <button type="submit">Đăng bài</button>
    </form>
  );
}

3. Experience tốt hơn với useFormStatus & useActionState

Để làm UI xịn (nút Loading, hiển thị lỗi), React cung cấp các Hooks:

useFormStatus: Theo dõi trạng thái nút bấm

(Phải dùng bên trong component con của Form).

tsx:
function SubmitButton() {
  const { pending } = useFormStatus();
  return <button disabled={pending}>{pending ? 'Đang gửi...' : 'Gửi'}</button>;
}

useActionState (React 19/Next 15): Quản lý State của Action

tsx:
const [state, formAction] = useActionState(createPost, { message: "" });

return (
  <form action={formAction}>
     {state.message && <p className="error">{state.message}</p>}
     ...
  </form>
);

4. Bảo mật (Security)

Server Actions mặc định là public endpoints. Đừng bao giờ tin tưởng Input từ Client:

  • Luôn Validate: Dùng Zod để kiểm tra formData.
  • Authentication: Kiểm tra session bên trong Action.
  • Server-only code: Function chỉ được phép chạy trên Server.

5. Revalidation (Cập nhật UI)

Đây là điểm mạnh nhất. Sau khi Database đổi, bạn chỉ cần gọi:

  • revalidatePath('/'): Cập nhật route cụ thể.
  • revalidateTag('posts'): Cập nhật theo tag (dùng trong fetch).

Kết luận

Server Actions không chỉ giúp code ngắn hơn, nó còn giúp ứng dụng progressive enhancement (vẫn chạy được khi user chưa tải xong JavaScript).

  • Dùng cho mọi tác vụ ghi dữ liệu (Add, Edit, Delete).
  • Kết hợp với Zod để type-safe từ Server sang Client.
Quảng cáo
mdhorizontal