Lifting State Up — React

Bayangin form login dengan komponen di kiri dan di kanan. Pas user ngetik email belum valid, button harus disabled. Tapi gak tahu apa email valid — itu state di

Bayangin form login dengan komponen <EmailInput> di kiri dan <SubmitButton> di kanan. Pas user ngetik email belum valid, button harus disabled. Tapi <SubmitButton> gak tahu apa email valid — itu state di dalam <EmailInput>. Cara React nyelesaiin: angkat state ke parent terdekat yang nge-host kedua komponen. Email state pindah ke parent → di-pass ke <EmailInput> (untuk display) dan ke <SubmitButton> (untuk cek valid). State sentralisasi di satu tempat = "single source of truth".

💡 Pattern fundamental. Lifting state up adalah salah satu pattern PALING SERING dipake di React. Tiap kali 2+ komponen butuh sync data — naikkan state ke parent. Lawan dari pattern ini: prop drilling (state di terlalu atas, drilled lewat banyak level) — solusi: Context API (lesson selanjutnya).

function Display({ value }) {
  return <span>{value}</span>
}

function Controls({ onIncrement }) {
  return <button onClick={onIncrement}>+1</button>
}

function App() {
  // State diangkat ke parent — Display + Controls share count
  const [count, setCount] = useState(0)

  return (
    <div>
      <Display value={count} />
      <Controls onIncrement={() => setCount(c => c + 1)} />
    </div>
  )
}

Pattern Lengkap

function TempInput({ scale, value, onChange }) {
  return (
    <div>
      <label>Suhu dalam {scale}: </label>
      <input value={value} onChange={(e) => onChange(e.target.value)} />
    </div>
  )
}

function Calculator() {
  // STATE LIFTED — kedua input share state
  const [temperature, setTemperature] = useState("")
  const [scale, setScale] = useState("c")

  return (
    <div>
      <TempInput
        scale="Celsius"
        value={scale === "c" ? temperature : convertCtoF(temperature)}
        onChange={(t) => { setScale("c"); setTemperature(t) }}
      />
      <TempInput
        scale="Fahrenheit"
        value={scale === "f" ? temperature : convertFtoC(temperature)}
        onChange={(t) => { setScale("f"); setTemperature(t) }}
      />
    </div>
  )
}

Ketik di input Celsius → state update → input Fahrenheit otomatis convert + display. Beautifully synced.

Prinsip

  1. Identifikasi state yang dibutuhkan bersama — komponen mana yang akses?
  2. Cari parent TERDEKAT yang nge-host semua komponen tersebut
  3. Pindahkan state ke parent — pakai useState/useReducer di parent
  4. Pass DATA via props ke bawah<Child value={state} />
  5. Pass FUNCTION via props untuk update<Child onChange={setState} />

🎭 Analogi sehari-hari

Lifting state itu kayak dapur bersama di kontrakan. Dulu tiap kamar punya dapur sendiri-sendiri (state lokal di tiap komponen) — boros, ribet sinkronisasi (kalau kamar A masak nasi, kamar B gak otomatis tau). Renovasi: pindahin dapur ke ruang tengah (parent), semua kamar share dapur yang sama. Si A masak → si B liat panci di kompor → tahu nasi udah siap. Single source of truth: satu nasi, satu kompor, semua kamar paham. Plus efisien — gak perlu duplikasi peralatan masak. Risiko: ruang tengah (parent) kepenuhan kalo terlalu banyak masak — itu sinyal extract ke "dapur regional" (Context API).

⚠️ Jebakan yang sering ditemui

🎯 State di mana — local atau lifted?

  • Cuma 1 komponen pakai → state lokal (useState di komponen itu)
  • 2+ sibling komponen pakai → lift ke parent terdekat
  • Many distant components pakai (3+ level) → Context API (atau state management library)
  • State global (theme, user, lang) → Context API
  • Server state (data dari API) → TanStack Query (cache + sync built-in)
  • URL state (filter, page, search) → URL params (react-router atau next router)

Aturan: state di posisi paling DEKAT dengan yang butuh. Lift secukupnya. Naikin ke Context cuma kalau drilling > 2-3 level.

TL;DR: Lifting state up = pindahin shared state ke komponen parent terdekat yang nge-host komponen yang butuh. Pass DATA ke child via props (read-only), pass FUNCTION untuk update. "Single source of truth" — sync otomatis antar sibling. Lifting terlalu tinggi = banyak prop drilling. Lifting terlalu rendah = duplicate state di sibling. > 3 level drilling = waktunya Context API.

Yang akan kamu pelajari