Pernah frustrasi karena dua komponen React kamu tidak bisa "ngobrol" satu sama lain? Kamu ganti state di satu komponen, tapi komponen lain tidak tahu apa-apa. Nah, itulah masalah klasik yang diselesaikan oleh teknik lifting state up React parent child component. Artikel ini adalah bagian dari Seri Belajar React: React From Zero to Zorro — dan di sini kita akan kupas tuntas cara dua komponen bisa berkomunikasi dengan elegan, tanpa ribet.
Bayangkan kamu baru kenal React, antusias bikin tombol counter, tapi tiba-tiba bingung: "Bagaimana caranya komponen A tahu kalau komponen B sudah diklik?" Tenang — setelah baca ini, kamu akan paham betul polanya.
Lifting State Up = memindahkan state ke komponen induk (parent) agar bisa dibagikan ke komponen anak (child) yang membutuhkannya.
Ini adalah salah satu pola fundamental React yang wajib dikuasai sebelum lanjut ke state management library seperti Redux atau Zustand.
🏠 Analogi: Lifting State Up Itu Seperti Papan Pengumuman Keluarga
Bayangkan sebuah keluarga dengan tiga anggota: Ayah (Parent), Anak A, dan Anak B. Anak A ingin bilang ke Anak B: "Aku sudah makan!" Tapi mereka tidak bisa langsung ngobrol. Solusinya? Tulis di papan pengumuman yang dikelola Ayah. Anak A bilang ke Ayah, Ayah catat, dan Anak B baca dari papan itu.
Begitu pula di React. Komponen-komponen "saudara" (sibling) tidak bisa langsung berbagi data. Solusinya: angkat (lift) state ke komponen parent, lalu bagikan ke child lewat props.
Tips
Kalau dua komponen butuh akses ke data yang sama, cari parent terdekat yang menjadi ancestor keduanya. Itulah tempat paling tepat untuk menaruh state tersebut.
┌─────────────────────────┐
│ <App /> (Parent) │ ← state disimpan di sini
│ state: jumlah = 5 │
└───────────┬─────────────┘
│ props
┌─────────┴──────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ <Tampilan /> │ │ <Tombol /> │
│ (child A) │ │ (child B) │
│ props.jumlah │ │ props.onKlik │
└───────────────┘ └───────────────┘
⚙️ Cara Kerja Parent-Child Component: Props dan Callback Function
Dalam komunikasi parent-child component React, ada dua arah aliran data:
- Parent → Child: lewat props
- Child → Parent: lewat callback function (fungsi yang dikirim via props)
Inilah inti dari pola lifting state up. Kita tidak bisa "kirim data ke atas" secara langsung, tapi kita bisa memanggil fungsi dari parent yang sudah dikirim ke child.
Fakta Menarik
React sengaja membuat data mengalir satu arah (one-way data flow) — dari parent ke child. Ini bukan keterbatasan, melainkan desain yang disengaja agar aplikasi lebih mudah di-debug dan diprediksi.
Langkah Implementasi Lifting State Up:
Identifikasi state yang perlu di-share
Tanyakan: "Siapa saja komponen yang butuh data ini?" Kalau lebih dari satu, berarti state itu tidak boleh ada di salah satu child tersebut.
Pindahkan state ke komponen parent
Buat useState di komponen parent, bukan di child.
Kirim state ke child via props
Child yang hanya perlu menampilkan data, cukup terima nilai state lewat props.
Kirim fungsi setter ke child yang perlu mengubah state
Child yang perlu mengubah state, terima fungsi callback dari parent. Saat dipanggil, state di parent otomatis berubah dan semua child yang berlangganan data itu ikut update.
💻 Contoh Kode: Lifting State Up React Parent Child Component
Kita akan buat contoh sederhana: dua child component — satu untuk menampilkan skor, satu lagi untuk menambah skor. Keduanya harus tahu nilai yang sama, jadi state kita angkat ke parent.
❌ Cara yang SALAH (state terpisah di masing-masing child):
// ❌ State terpisah = data tidak sinkron! function TampilSkor() { const [skor, setSkor] = useState(0); // state sendiri return <p>Skor: {skor}</p>; } function TombolTambah() { const [skor, setSkor] = useState(0); // state BERBEDA! return <button onClick={() => setSkor(skor + 1)}>+1</button>; } // TampilSkor tidak pernah tahu skor berubah 😢
✅ Cara yang BENAR (lifting state up ke parent):
import { useState } from 'react'; // Child A: hanya MENAMPILKAN skor function TampilSkor({ skor }) { return ( <div style={{ padding: '16px', fontSize: '24px' }}> 🏆 Skor Kamu: <strong>{skor}</strong> </div> ); } // Child B: hanya MENGUBAH skor lewat callback function TombolTambah({ onTambah }) { return ( <button onClick={onTambah}> ➕ Tambah Skor </button> ); } // Parent: menyimpan state, membagikan ke child function App() { const [skor, setSkor] = useState(0); // ← state di parent! const tambahSkor = () => setSkor(skor + 1); return ( <div> <TampilSkor skor={skor} /> {/* terima nilai */} <TombolTambah onTambah={tambahSkor} /> {/* terima fungsi */} </div> ); }
Insight Penting
Perhatikan penamaan props fungsi: konvensi React menggunakan awalan on untuk event handler — misalnya onTambah, onChange, onSubmit. Ini bukan aturan wajib, tapi sangat membantu keterbacaan kode.
📊 Perbandingan: State di Child vs Lifting State Up ke Parent
| Aspek | State di Child | Lifting State Up |
|---|---|---|
| Lokasi State | Terpisah di masing-masing child | Terpusat di parent |
| Sinkronisasi Antar Komponen | ❌ Tidak bisa | ✅ Otomatis sinkron |
| Kapan Digunakan | Data hanya dipakai 1 komponen | Data dipakai 2+ komponen |
| Kompleksitas | Lebih sederhana | Sedikit lebih terstruktur |
| Kemudahan Debugging | Sulit (state tersebar) | Mudah (satu sumber kebenaran) |
Lifting state up menerapkan prinsip "Single Source of Truth" — hanya ada SATU tempat yang menyimpan kebenaran data. Ini membuat aplikasi React kamu jauh lebih mudah di-maintain seiring aplikasi makin besar. Ingat: lebih baik sedikit over-engineered di awal daripada susah refactor di tengah jalan.
Perhatian
Jangan terlalu semangat mengangkat semua state ke parent tertinggi! Ini disebut "prop drilling" dan bisa jadi masalah baru. State seharusnya ada di level paling rendah yang masih mencukupi kebutuhan semua komponen yang menggunakannya.
🚀 Contoh Nyata: Form Input dengan Lifting State Up
Mari kita lihat contoh lebih realistis — form input nama dan komponen yang menampilkan sambutan. Kedua komponen perlu akses ke nilai input yang sama.
import { useState } from 'react'; // Child: input form function InputNama({ nama, onUbahNama }) { return ( <input type="text" value={nama} onChange={(e) => onUbahNama(e.target.value)} placeholder="Masukkan namamu..." /> ); } // Child: tampilan sambutan function Sambutan({ nama }) { return ( <h2> {nama ? `Halo, ${nama}! 👋` : 'Halo, Siapa kamu? 🤔'} </h2> ); } // Parent: state di sini! function App() { const [nama, setNama] = useState(''); return ( <div> <InputNama nama={nama} onUbahNama={setNama} /> <Sambutan nama={nama} /> </div> ); }
Insight Penting
Perhatikan baris onUbahNama={setNama} — kita langsung mengoper fungsi setNama dari useState langsung ke child. Tidak perlu bungkus dalam fungsi tambahan kalau logikanya sesederhana ini. Kode yang ringkas = kode yang baik!
Bagian dari Seri
Seri Belajar React: React From Zero to Zorro
Artikel ini adalah bagian dari seri lengkap 16 artikel belajar React dari nol sampai mahir. Klik link di bawah untuk melihat daftar isi lengkapnya!
🗂️ Lihat Daftar Isi Lengkap →
No comments:
Post a Comment