Pola Praktis Cara Menggunakan Event Handler Next Js untuk onClick dan Form

Cara menggunakan event handler Next.js yang benar adalah menaruh onClick, onChange, dan onSubmit di Client Component dengan "use client" di baris pertama. Server Component tidak bisa menyimpan fungsi klik karena kodenya jalan di server dan tidak punya akses ke browser. Pola praktisnya: halaman tetap Server Component, lalu buat komponen tombol atau form kecil yang client khusus untuk interaksi.

Jawaban Cepat: onClick dan onChange Hanya Jalan di Client

Event handler React butuh browser. Itu sebabnya file yang berisi onClick wajib diawali "use client".

"use client";

export default function TombolSimpan() {
  function handleKlik() {
    alert("Tersimpan di browser");
  }

  return <button onClick={handleKlik}>Simpan</button>;
}

Bedakan dua jenis handler di App Router. Handler browser seperti onClick berjalan di client untuk UI. Server Action berjalan di server untuk tulis database atau validasi sensitif.

Aturan Server Component untuk Event Handler

File app/page.tsx tanpa "use client" adalah Server Component. Menaruh onClick={() => ...} di sana memicu error karena fungsi tidak bisa diserialisasi ke client.

Solusinya bukan mengubah semua halaman jadi client. Pisahkan bagian interaktif ke file kecil, lalu impor dari Server Component.

  • onClick, onChange, onBlur wajib di Client Component.
  • onSubmit form interaktif juga butuh client bila memakai state atau preventDefault.
  • Akses window, document, dan localStorage hanya aman di event atau useEffect client.

Langkah Praktis Pasang Event di App Router

  1. Buat file baru untuk UI interaktif, contoh app/Tombol.tsx, lalu tulis "use client" paling atas.
  2. Tulis handler dengan event bila butuh nilai input atau cegah reload form.
  3. Impor komponen client itu dari page.tsx Server Component dan teruskan data lewat props.
"use client";
import { useState } from "react";

export function FormNama({ onSimpan }: { onSimpan: (nama: string) => void }) {
  const [nama, setNama] = useState("");

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        onSimpan(nama);
      }}
    >
      <input value={nama} onChange={(e) => setNama(e.target.value)} />
      <button type="submit">Kirim</button>
    </form>
  );
}

Untuk simpan ke database, teruskan Server Action lewat props atau pakai atribut action pada form. Validasi ulang di server tetap wajib walau client sudah cek input.

Tabel Kesalahan Umum dan Perbaikannya

Masalah Penyebab Solusi
Handler tidak jalan Tombol ada di Server Component Pindah tombol ke file "use client"
Hydration error State awal beda server dan client Samakan nilai awal, baca waktu atau storage di useEffect
window is not defined Browser API dipanggil saat render server Panggil di dalam handler atau useEffect

FAQ

Apakah semua halaman harus use client?

Tidak. Biarkan halaman server, hanya komponen tombol dan form yang client.

Bisakah event handler memanggil Server Action?

Bisa. Impor Server Action lalu panggil dari handler client, dengan validasi input di server.

Kapan pakai Route Handler bukan onClick biasa?

Pakai Route Handler untuk API GET, POST, webhook, atau upload yang butuh respons HTTP eksplisit.