nextjsproyekserver-actionsMenengah5 mnt baca

Proyek: Todo App Full

Tugas: bangun aplikasi todo lengkap dengan Server Actions.

Misi: Todo App dari nol

Empat modul terakhir memberimu semua senjata: Server Actions, validasi, pending state, useActionState, optimistic update, dan revalidatePath. Sekarang rangkai semuanya menjadi aplikasi todo yang benar-benar berfungsi. Ini peta langkahnya, bukan kode jadi. Kamu yang menulis kodenya.

Langkah 0: struktur file

Buat folder app/todos/ dengan file-file ini, masing-masing satu tanggung jawab:

  • app/todos/page.tsx, Server Component: fetch data, render daftar + form
  • app/todos/actions.ts, semua Server Actions (tambah, toggle, hapus)
  • app/todos/data.ts, lapisan penyimpanan (baca/tulis JSON)
  • app/todos/AddForm.tsx, Client Component: form tambah + pesan error
  • app/todos/TodoList.tsx, Client Component: daftar + toggle optimistik

Satu file satu tugas, jadi kalau ada bug kamu langsung tahu file mana yang dibuka.

Langkah 1: lapisan data dulu

Mulai dari data.ts: simpan todos di file JSON (todos.json di root project) lewat getTodos() dan saveTodos(). Kenapa JSON bukan array in-memory? Dev server me-restart modul saat kamu mengedit file sehingga array in-memory ikut ter-reset, sedangkan file JSON selamat.

tsx
// app/todos/data.ts (kerangka, lengkapi sendiri)
import { readFile, writeFile } from "fs/promises";
import { join } from "path";

const FILE = join(process.cwd(), "todos.json");

export type Todo = { id: string; judul: string; selesai: boolean };

export async function getTodos(): Promise<Todo[]> {
  // baca FILE; kembalikan [] bila file belum ada (try/catch)
}

export async function saveTodos(todos: Todo[]): Promise<void> {
  // tulis JSON.stringify(todos) ke FILE
}

Langkah 2: tiga Server Actions

Di actions.ts, tulis tambahTodo, toggleTodo, dan hapusTodo:

tsx
// app/todos/actions.ts (kerangka)
"use server";
import { revalidatePath } from "next/cache";
import { z } from "zod";
import { getTodos, saveTodos, type Todo } from "./data";

const Skema = z.object({ judul: z.string().min(3, "Judul minimal 3 karakter") });

export async function tambahTodo(_prev: unknown, formData: FormData) {
  // 1. validasi Zod → return { error } bila gagal
  // 2. buat todo baru (id: crypto.randomUUID()), simpan
  // 3. revalidatePath("/todos")
}

export async function toggleTodo(id: string) {
  // 1. beri delay 1 detik (agar efek optimistik terlihat)
  // 2. balik flag selesai, simpan
  // 3. revalidatePath("/todos")
}

export async function hapusTodo(id: string) {
  // 1. buang todo dengan id tersebut, simpan
  // 2. revalidatePath("/todos")
}

Aturannya: semua bertanda "use server", semua mutasi lewat sini (tidak ada API route), dan setiap aksi yang sukses memanggil revalidatePath("/todos").

Langkah 3: form tambah dengan pesan error

AddForm.tsx memakai useActionState (modul 41): tampilkan error validasi dari server tepat di bawah input, tombol disable saat pending, dan kosongkan input setelah sukses. Ini menguji pemahamanmu tentang state hasil action.

Langkah 4: daftar dengan toggle optimistik

TodoList.tsx memakai useOptimistic (modul 42) untuk toggle selesai/belum. Karena toggleTodo punya delay 1 detik, efek instannya akan terlihat jelas: centang langsung berubah, server menyusul. Tambahkan try/catch + router.refresh() untuk rollback bila gagal.

Langkah 5: hapus dengan konfirmasi

Satu tombol hapus per item. Karena hapus tidak bisa di-undo, JANGAN optimistik di sini (ingat aturan modul 42). Tampilkan confirm() bawaan browser dulu, baru panggil hapusTodo bila user setuju.

Langkah 6: uji seperti QA

  • Tambah todo kosong → harus muncul error, bukan todo kosong.
  • Tambah "ab" (2 karakter) → error Zod "minimal 3 karakter".
  • Toggle 5x cepat → UI tetap konsisten, tidak ada flicker aneh.
  • Refresh browser → data tetap ada (JSON bekerja).
  • Matikan JavaScript di DevTools → form tambah masih berfungsi (progressive enhancement).

Kalau semua lolos, kamu resmi paham Server Actions end-to-end. Kirim kodemu untuk dinilai AI tutor.

Catatan teknis: Kriteria penilaian ada di assignment modul ini: Server Actions untuk semua mutasi, validasi Zod di server, optimistic update saat toggle, dan revalidatePath setelah mutasi.

Tantangan

Rencana dulu

Sebelum ngoding, tulis daftar file yang akan kamu buat (mis. app/todos/page.tsx, app/todos/actions.ts) beserta fungsi masing-masing dalam 1 kalimat.

Tugas

Todo App dengan Server Actions

Bangun aplikasi todo lengkap: tambah (validasi Zod), toggle selesai (optimistic), hapus. Semua mutasi via Server Actions. Tulis kode lengkap (actions + komponen) di bawah.

Kriteria penilaian:

  • Server Action untuk tambah/toggle/hapus dengan "use server"
  • Validasi Zod di server sebelum simpan
  • Optimistic update saat toggle
  • revalidatePath setelah mutasi

AI tutor akan memeriksa bug, kesalahan syntax, dan memberi saran perbaikan.

Kuis Bab

Uji pemahamanmu: Server Actions & Form

Jawab 5 soal berikut, lalu tekan "Periksa Jawaban".

1.Apa itu Server Action?

2.Di mana validasi keamanan harus dilakukan?

3.Apa fungsi useActionState?

4.Kapan optimistic update TIDAK boleh dipakai?

5.Apa yang dilakukan revalidatePath("/todos")?