K

Command Palette

Search for a command to run...

Daftar

Form & Input di React

Pelajari cara membuat form interaktif di ReactJS dan mengelola nilai input field menggunakan konsep 'Controlled Components' dengan state dan event handler.

"Nangkep" Input Pengguna: Jurus Ngelola Form & Controlled Components di React!

Udah bisa nampilin data dan bikin UI yang lumayan? Keren! Sekarang, gimana caranya kita ngambil input atau data dari pengguna? Misalnya, bikin form pendaftaran, kolom komentar, atau search bar. Di sinilah kita bakal banyak berurusan sama elemen-elemen form HTML (<form>, <input>, <textarea>, <select>) di dalem React.

Nanganin form di React itu punya "gaya"-nya sendiri, dan konsep utamanya adalah Controlled Components (Komponen Terkontrol).

Apa Itu Controlled Components?

Di HTML biasa, elemen form kayak <input> itu punya "state"-nya sendiri di dalem DOM. Browser yang ngurusin nilainya pas pengguna ngetik.

Nah, di React, kita biasanya pengen state aplikasi React kita yang jadi "sumber kebenaran tunggal" (single source of truth) buat nilai input form itu. Artinya:

  1. Nilai input field (misal, apa yang diketik di <input type="text">) itu disimpen di state komponen React.
  2. Setiap kali pengguna ngetik atau ngubah input, kita update state React itu.
  3. Nilai yang ditampilin di input field itu sendiri diambil dari state React tersebut (lewat prop value).

Komponen input yang nilainya diatur sepenuhnya sama state React kayak gini disebut Controlled Component. Ini ngasih kita kontrol penuh atas data form dan bikin data itu gampang diakses dan divalidasi.

Langkah-Langkah Bikin Controlled Component buat Input Teks

Mari kita liat contoh paling umum: input teks.

HTML Dasar (sebelum di-React-in):

html
<form>
  <label htmlFor="nama">Nama:</label>
  <input type="text" id="nama" />
  <button type="submit">Kirim</button>
</form>

Versi React dengan Controlled Component:

jsx
import React, { useState } from 'react';
 
function FormNama() {
  // 1. Bikin state buat nyimpen nilai input nama
  const [namaInput, setNamaInput] = useState(''); // Nilai awal string kosong
 
  // 2. Fungsi handler buat ngupdate state pas input berubah
  const handleInputChange = (event) => {
    // event.target ngacu ke elemen input
    // event.target.value ngambil nilai terbaru dari input
    setNamaInput(event.target.value); 
    console.log("Nilai input sekarang:", event.target.value); 
  };
 
  // 3. Fungsi handler buat pas form di-submit
  const handleSubmit = (event) => {
    event.preventDefault(); // Mencegah reload halaman default pas form submit
    alert(`Halo, ${namaInput}! Namamu sudah terkirim (pura-puranya).`);
    // Di sini kamu bisa ngelakuin sesuatu sama namaInput (misal, kirim ke API)
    setNamaInput(''); // Kosongin lagi input field setelah submit (opsional)
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="inputNamaPengguna">Nama Pengguna:</label>
      <input 
        type="text" 
        id="inputNamaPengguna"
        value={namaInput}      // 4. Nilai input DIKONTROL sama state 'namaInput'
        onChange={handleInputChange} // 5. Setiap perubahan di input manggil handleInputChange
        placeholder="Ketik namamu di sini..."
      />
      <button type="submit">Kirim Nama</button>
    </form>
  );
}
 
export default FormNama;

Bedah Kodenya:

  1. useState(''): Kita bikin state namaInput dengan nilai awal string kosong. setNamaInput adalah fungsi buat ngubah state ini.
  2. handleInputChange(event): Fungsi ini bakal dijalanin setiap kali ada perubahan di input field (onChange event).
    • event.target.value ngasih kita nilai terbaru yang diketik pengguna di input field itu.
    • Kita manggil setNamaInput(event.target.value) buat ngupdate state namaInput kita sama nilai terbaru itu. React bakal nge-re-render komponen.
  3. handleSubmit(event): Fungsi ini jalan pas tombol submit di form diklik (atau pengguna neken Enter di input field).
    • event.preventDefault();: Ini WAJIB biar halaman gak nge-reload (perilaku default form HTML).
    • Kita bisa ngelakuin apa aja sama nilai namaInput yang udah ada di state (misal, nampilin alert, kirim ke server).
    • setNamaInput('');: (Opsional) Kita kosongin lagi input field-nya setelah submit.
  4. <input value={namaInput} ... />: Ini bagian kuncinya! Atribut value dari input field kita di-set langsung dari state namaInput. Jadi, apa yang tampil di input field itu selalu sinkron sama state React kita.
  5. <input onChange={handleInputChange} ... />: Atribut onChange kita pasangin sama fungsi handleInputChange. Jadi, setiap kali pengguna ngetik (nilainya berubah), handleInputChange dipanggil, state diupdate, dan input field di-re-render dengan nilai baru dari state.

Ini siklusnya: Pengguna ngetik -> onChange kepicu -> Handler update state -> React re-render -> Input field nampilin nilai state baru.

Menangani Berbagai Jenis Input Form

Konsep controlled components ini berlaku buat berbagai jenis input form:

<textarea>

Mirip kayak input type="text", tapi pake value prop juga (beda sama HTML biasa yang teksnya di antara tag).

jsx
function FormKomentar() {
  const [komentar, setKomentar] = useState('');
 
  const handleKomentarChange = (event) => {
    setKomentar(event.target.value);
  };
 
  // ... (handleSubmit function) ...
 
  return (
    <form /* onSubmit={handleSubmit} */ >
      <label htmlFor="areaKomentar">Komentar Anda:</label>
      <textarea 
        id="areaKomentar"
        value={komentar}
        onChange={handleKomentarChange}
        rows="4"
        placeholder="Tulis komentarmu..."
      />
      <button type="submit">Kirim Komentar</button>
    </form>
  );
}

<select> (Dropdown)

Nilai dari <select> juga diatur pake prop value di tag <select>-nya, yang nilainya harus cocok sama salah satu value dari <option> di dalemnya.

jsx
function FormPilihan() {
  const [pilihanBuah, setPilihanBuah] = useState('jeruk'); // Nilai awal 'jeruk'
 
  const handleBuahChange = (event) => {
    setPilihanBuah(event.target.value);
  };
 
  // ... (handleSubmit function) ...
 
  return (
    <form /* onSubmit={handleSubmit} */ >
      <label htmlFor="selectBuah">Pilih Buah Favorit:</label>
      <select id="selectBuah" value={pilihanBuah} onChange={handleBuahChange}>
        <option value="apel">Apel</option>
        <option value="jeruk">Jeruk</option>
        <option value="mangga">Mangga</option>
        <option value="pisang">Pisang</option>
      </select>
      <p>Kamu memilih: {pilihanBuah}</p>
      <button type="submit">Simpan Pilihan</button>
    </form>
  );
}

Pas salah satu <option> dipilih, event.target.value di handleBuahChange bakal ngasih nilai dari value atribut <option> itu, terus state pilihanBuah diupdate, dan <select> bakal otomatis nampilin opsi yang sesuai sama state baru itu.

<input type="checkbox">

Checkbox agak beda. Nilainya (tercentang atau enggak) diatur pake prop checked (boolean), dan kita dengerin event onChange buat ngupdate state boolean itu. event.target.checked bakal ngasih status centangnya.

jsx
function FormCheckbox() {
  const [setujuSyarat, setSetujuSyarat] = useState(false);
 
  const handleCheckboxChange = (event) => {
    setSetujuSyarat(event.target.checked); // true kalau dicentang, false kalau enggak
  };
 
  return (
    <form>
      <label>
        <input 
          type="checkbox"
          checked={setujuSyarat}
          onChange={handleCheckboxChange}
        />
        Saya setuju dengan syarat dan ketentuan.
      </label>
      <p>Status persetujuan: {setujuSyarat ? "Setuju" : "Tidak Setuju"}</p>
    </form>
  );
}

<input type="radio">

Radio button biasanya dipake berkelompok (dengan name atribut yang sama). Kamu perlu satu state buat nyimpen nilai radio button mana yang lagi kepilih di grup itu.

jsx
function FormRadio() {
  const [gender, setGender] = useState('pria'); // Nilai awal
 
  const handleGenderChange = (event) => {
    setGender(event.target.value);
  };
 
  return (
    <form>
      <p>Pilih Jenis Kelamin:</p>
      <label>
        <input 
          type="radio" 
          value="pria" 
          checked={gender === 'pria'} // Checked kalau state 'gender' sama dengan value radio ini
          onChange={handleGenderChange} 
        />
        Pria
      </label>
      <label style={{ marginLeft: '10px' }}>
        <input 
          type="radio" 
          value="wanita" 
          checked={gender === 'wanita'} 
          onChange={handleGenderChange} 
        />
        Wanita
      </label>
      <p>Jenis kelamin terpilih: {gender}</p>
    </form>
  );
}

Menangani Multiple Inputs (Banyak Input Field)

Kalau form-mu punya banyak input field, bikin state dan fungsi handler satu-satu buat tiap input bisa jadi capek. Ada cara yang lebih pinter: pake satu fungsi handler dan satu objek state (atau beberapa state individual yang diupdate berdasarkan name atribut input).

Contoh dengan Beberapa State Individual dan name Atribut:

jsx
function FormLengkap() {
  const [nama, setNama] = useState('');
  const [email, setEmail] = useState('');
 
  const handleInputChange = (event) => {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name; // Ambil atribut 'name' dari input
 
    if (name === "inputNamaForm") {
      setNama(value);
    } else if (name === "inputEmailForm") {
      setEmail(value);
    }
  };
 
  // ... (handleSubmit) ...
 
  return (
    <form /* onSubmit={handleSubmit} */>
      <div>
        <label htmlFor="namaUser">Nama:</label>
        <input 
          type="text" 
          id="namaUser" 
          name="inputNamaForm" /* Kasih atribut name! */
          value={nama} 
          onChange={handleInputChange} 
        />
      </div>
      <div>
        <label htmlFor="emailUser">Email:</label>
        <input 
          type="email" 
          id="emailUser"
          name="inputEmailForm" /* Kasih atribut name! */
          value={email}
          onChange={handleInputChange}
        />
      </div>
      <button type="submit">Daftar</button>
    </form>
  );
}

Di sini, kita pake atribut name di tiap input buat ngidentifikasi input mana yang berubah di dalem fungsi handleInputChange.

Contoh dengan Satu Objek State (Lebih Umum buat Form Kompleks):

jsx
function FormObjekState() {
  const [formData, setFormData] = useState({
    username: '',
    password: ''
  });
 
  const handleChange = (event) => {
    const { name, value } = event.target; // Destructure name dan value dari event.target
    setFormData(prevState => ({
      ...prevState, // Salin semua state lama
      [name]: value  // Update state yang propertinya cocok sama 'name' input
                     // [name] ini computed property name ES6
    }));
  };
  
  // ... handleSubmit ...
  return (
    <form>
      <input type="text" name="username" value={formData.username} onChange={handleChange} />
      <input type="password" name="password" value={formData.password} onChange={handleChange} />
      {/* ... */}
    </form>
  );
}

Cara ini lebih scalable kalau input field-nya banyak.


Nanganin form dan input pake konsep Controlled Components ini adalah cara standar di React. Awalnya mungkin kerasa agak "bertele-tele" karena semua nilai harus lewat state. Tapi, ini ngasih kamu kontrol penuh atas data, mempermudah validasi, dan bikin alur data di aplikasimu jadi lebih jelas dan prediktabel.

Jangan ragu buat nyoba bikin macem-macem form dengan berbagai jenis input. Ini skill yang bakal kepake banget!

Kuis Form & Input di ReactJS

Pertanyaan 1 dari 5

Apa yang dimaksud dengan 'Controlled Component' dalam konteks form di ReactJS?