Jangan Kirim Fungsi Langsung: Cara Mengatasi Function Cannot Be Passed To Client Component

Pindahkan fungsi handler ke dalam Client Component, lalu kirim hanya data serializable seperti string, number, atau boolean dari Server Component. Error function cannot be passed to client component muncul karena Next.js App Router mengirim props dari server ke client lewat serialisasi, dan fungsi tidak bisa melewati proses itu.

Penyebab Function Cannot Be Passed to Client Component Muncul

Server Component berjalan di server dan hasilnya dikirim sebagai payload ke browser. Client Component menerima payload itu, jadi semua props harus bisa diserialisasi.

Fungsi inline, closure, dan callback yang dibuat di Server Component menyimpan referensi memori server. Referensi itu hilang saat diserialisasi, sehingga React menolaknya.

Pola yang sering memicu error:

  • Mengirim onClick={() => …} dari Server Component ke tombol client
  • Mengirim formatter atau helper seperti formatDate sebagai props
  • Mengirim async handler database langsung ke form client

Tabel Troubleshooting Error Props Fungsi

Baca log terminal Next.js, bukan console browser. Cari nama komponen Server Component pengirim dan Client Component penerima untuk menemukan batas yang bocor.

Masalah Penyebab Solusi
Fungsi inline di props Closure dibuat di server Pindah handler ke Client Component
Async handler server Akses database langsung Ubah jadi Server Action
Date, Map, class instance Tidak serializable penuh Kirim string atau object polos

Pisah komponen kalau handler butuh state, event, atau browser API. Cukup pindah logika kalau masalahnya hanya format tanggal atau transformasi data sederhana.

Cara Memperbaiki Props Fungsi Tanpa Merusak Struktur

  1. Temukan batas client dari stack trace, lalu tandai komponen interaktif dengan use client.
  2. Pindahkan onClick, onChange, dan onSubmit ke Client Component tersebut.
  3. Kirim hanya data serializable dari Server Component, misalnya productId atau initialName.
  4. Gunakan Server Action untuk tulis database, validasi input di server sebelum menyimpan.
// Salah: Server Component mengirim fungsi
<CheckoutButton onPay={() => processPayment(id)} />

// Benar: kirim data saja
// app/checkout/page.tsx
import CheckoutButton from "./CheckoutButton";
export default function Page() {
  return <CheckoutButton productId="p-123" />;
}

// ./CheckoutButton.tsx
"use client";
export default function CheckoutButton({ productId }) {
  return <button onClick={() => console.log(productId)}>Bayar</button>;
}
// Server Action sebagai pengganti callback server
"use server";
export async function saveOrder(formData: FormData) {
  const productId = String(formData.get("productId") ?? "");
  if (!productId) throw new Error("productId wajib diisi");
}

FAQ

Apakah semua fungsi dilarang dikirim ke Client Component?

Fungsi yang dibuat di Server Component tidak boleh dikirim sebagai props, tetapi fungsi yang dibuat di dalam Client Component tetap boleh dipakai.

Apakah Server Action boleh dipakai sebagai props fungsi?

Boleh, karena referensi Server Action dipertahankan framework dan dipanggil lewat request server, bukan lewat serialisasi fungsi biasa.

Kapan onClick tetap aman dipakai di App Router?

Aman kalau onClick didefinisikan di dalam Client Component yang memakai use client.