Belajar ReactJS - State & Event Handling
Episode 5 of 24

Belajar ReactJS - State & Event Handling

Episode ini membahas useState untuk local state, sistem synthetic events, controlled components untuk form input, serta cara React melakukan batching update dan re-render. Semua dibangun di atas komponen dan JSX dari episode sebelumnya.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Komponen yang statis hanya menampilkan data; aplikasi yang menarik adalah aplikasi yang bereaksi terhadap pengguna. Interaksi dimulai dari dua hal: state yang menyimpan nilai berubah, dan event handling yang menangkap aksi pengguna. Episode 5 membuat kalian menguasai keduanya.

Kita membahas useState untuk local state management, sistem synthetic events milik React, controlled components untuk form, lalu cara React melakukan batching dan re-render. Ini fondasi interaktivitas yang dipakai di semua episode berikutnya.

useState untuk Local State Management

Menyimpan Nilai yang Berubah

Hook useState mengembalikan sepasang nilai: nilai sekarang dan fungsi untuk memperbaruinya. Komponen akan di-render ulang setiap kali fungsi update dipanggil:

JSCounter dengan useState
import { useState } from "react"
 
function Counter() {
  const [hitung, setHitung] = useState(0)
 
  return (
    <div>
      <p>Hitungan: {hitung}</p>
      <button onClick={() => setHitung(hitung + 1)}>Tambah</button>
    </div>
  )
}

useState(0) menetapkan nilai awal 0 dan mengembalikan hitung plus setHitung. Memanggil setHitung selalu mengganti nilai dengan nilai baru dan memicu re-render — ini satu-satunya cara mengubah state yang benar.

Jangan Mutasi State Langsung

Mengubah nilai state secara langsung, seperti hitung = hitung + 1, tidak memicu render apa pun. React mendeteksi perubahan lewat fungsi update. Jika nilai baru bergantung pada nilai lama, gunakan bentuk callback:

JSUpdate dengan callback
const tambah = () => setHitung((sekarang) => sekarang + 1)

setHitung((sekarang) => sekarang + 1) menerima fungsi yang diberi nilai state paling baru. Bentuk ini wajib ketika ada beberapa update berurutan atau saat nilai baru dihitung dari state lama.

Event Handling dan Synthetic Events

Menangani Event di JSX

Event di React ditulis dengan awalan on dan huruf kapital, seperti onClick, onChange, dan onSubmit, dengan handler sebagai nilai:

JSBeberapa event handler
function FormSederhana() {
  const handleKlik = () => alert("Tombol diklik")
  const handleTeks = (e) => console.log("Diketik:", e.target.value)
 
  return (
    <div>
      <button onClick={handleKlik}>Klik</button>
      <input onChange={handleTeks} placeholder="Ketik di sini" />
    </div>
  )
}

onClick={handleKlik} menyerahkan referensi fungsi, bukan hasil pemanggilan. Jangan menulis onClick={handleKlik()} kecuali kalian memang ingin memanggilnya saat render.

Synthetic Event System

React membungkus event browser ke dalam SyntheticEvent agar perilakunya konsisten di semua browser. Event ini memiliki sifat yang sama seperti event asli, termasuk preventDefault dan stopPropagation, tapi dipasang lewat delegation ke root DOM sehingga penggunaan memori lebih hemat. Nama properti mengikuti camelCase, misalnya onChange, bukan onchange.

Controlled Components untuk Form Input

State sebagai Sumber Kebenaran

Pada controlled component, nilai input disimpan di state dan dikembalikan lewat atribut value. Setiap ketikan melewati onChange yang memperbarui state, sehingga state selalu sinkron dengan tampilan:

JSControlled input
import { useState } from "react"
 
function FormNama() {
  const [nama, setNama] = useState("")
 
  const handleSubmit = (e) => {
    e.preventDefault()
    console.log("Dikirim:", nama)
  }
 
  return (
    <form onSubmit={handleSubmit}>
      <input value={nama} onChange={(e) => setNama(e.target.value)} />
      <button type="submit">Simpan</button>
    </form>
  )
}

e.target.value membaca teks terkini dari event, lalu setNama menyimpannya ke state. Karena value selalu berasal dari state, nilai input tidak pernah menyimpang dari yang React ketahui — pola ini menjadi dasar validasi langsung di episode 11.

State Updates, Event Batching, dan Re-render

Batching Update di Dalam Satu Event

React menggabungkan beberapa pemanggilan setter dalam satu event menjadi satu render. Karena itu, membaca state lama di tengah batch tidak akan melihat nilai yang baru:

JSBatching update
const handleTambah = () => {
  setHitung(hitung + 1)
  setHitung(hitung + 1)
}

Dua pemanggilan di atas hanya menambah hitung sebanyak satu, karena keduanya membaca nilai yang sama dari render sebelumnya. Gunakan bentuk callback agar setiap update memakai hasil update sebelumnya:

JSUpdate berurutan yang benar
const handleTambah = () => {
  setHitung((sekarang) => sekarang + 1)
  setHitung((sekarang) => sekarang + 1)
}

setHitung((sekarang) => sekarang + 1) dijalankan berurutan, sehingga hasil akhirnya hitung bertambah dua. React menjalankan callback satu per satu di dalam satu batch render.

Perilaku Re-render

Ketika state berubah, React menjalankan ulang fungsi komponen dan membandingkan hasilnya dengan render sebelumnya lewat reconciliation. Hanya bagian yang benar-benar berubah yang diperbarui ke DOM. Memahami pola ini membantu kalian menghindari render boros — topik yang dibahas lebih dalam di episode 6 dan 15.

Penutup

Episode 5 memberi kalian otak untuk aplikasi: useState untuk menyimpan dan memperbarui nilai, synthetic events untuk menangkap interaksi, controlled components untuk form yang selalu sinkron, serta pemahaman batching dan re-render yang menjadi kunci membaca perilaku React.

Inti yang harus dibawa pulang:

  • useState mengembalikan nilai dan fungsi update; jangan pernah mutasi state langsung.
  • Gunakan bentuk callback saat update bergantung pada nilai state sebelumnya.
  • Handler event ditulis camelCase dan menerima SyntheticEvent.
  • Controlled component menempatkan nilai input di state lewat value dan onChange.
  • React melakukan batching: beberapa setter dalam satu event menghasilkan satu render.
  • Re-render dipicu oleh perubahan state, dan hanya bagian DOM yang berubah yang diperbarui.

Di episode 6 selanjutnya kita akan membahas effects & lifecycle dengan hooksuseEffect untuk side effects, cleanup effect dan dependency array, useMemo dan useCallback untuk optimasi, serta custom hooks untuk logika yang dipakai ulang. Aplikasi kalian mulai keluar dari layar: memuat data, mendengarkan event global, dan mengelola timer.