Di React, data mengalir dari parent ke child lewat props. Pola ini sederhana, eksplisit, dan biasanya cukup untuk sebagian besar komponen. Saat kebutuhan UI mulai lebih dalam, kita punya dua opsi yang sering dipakai: composition dan Context.
Composition: menyusun komponen dengan cara menyisipkan child, elemen, atau callback agar data tetap mengalir secara lokal.
Context: menyediakan data dari satu titik agar bisa dibaca banyak komponen di bawahnya tanpa harus meneruskan props di setiap level.
Prop drilling: kondisi saat props “dititipkan” lewat banyak komponen perantara hanya supaya sampai ke komponen yang benar-benar memakainya.
Kalau diringkas: prop drilling adalah gejala, composition adalah cara merapikan struktur, dan Context adalah alat berbagi data lintas level.
Kapan Prop Drilling Masih Wajar
Prop drilling bukan dosa. Dalam banyak kasus, ia justru pilihan paling jelas.
Gunakan props biasa kalau:
data hanya dipakai oleh satu atau dua level komponen
alur data masih mudah dibaca dari parent ke child
komponen perantara memang bertugas meneruskan data itu
perubahan state masih lokal dan tidak perlu dibagi luas
Model seperti ini sering lebih enak dibaca daripada menaruh sidebar dan content ke context, karena struktur UI-nya memang eksplisit.
Perbandingan Cepat
Pola
Cocok untuk
Kelebihan
Risiko
Props biasa
data pendek, jelas, lokal
paling eksplisit
prop drilling kalau terlalu dalam
Composition
UI fleksibel, reusable, struktur jelas
komponen tetap generik
bisa terlalu abstrak kalau dipaksa
Context
data lintas subtree
menghindari prop drilling
consumer jadi implisit, rerender bisa meluas
Jebakan Global State Kecil yang Dibesarkan Terlalu Dini
Ini jebakan yang sering kejadian di proyek React:
Ada state kecil, misalnya isOpen atau selectedTab.
Karena terlihat “akan dipakai banyak tempat”, state itu langsung dipindahkan ke Context.
Provider jadi lapisan baru yang belum tentu perlu.
Lama-lama semua hal ikut masuk ke provider yang sama.
Akhirnya, state kecil berubah jadi global state mini yang susah dirawat.
Masalah utamanya bukan Context-nya, tapi keputusan untuk mengglobalisasi sesuatu sebelum ada bukti kebutuhan.
Tanda-tandanya:
provider ditempatkan terlalu tinggi tanpa alasan struktural
satu context menampung state yang tidak saling berkaitan
komponen bawah bergantung pada value implisit, bukan props yang terlihat
sulit memahami kenapa rerender terjadi
testing jadi lebih berat karena banyak setup provider
Prinsip amannya: naikkan state hanya sejauh perlu, bukan sejauh mungkin.
Contoh Keputusan Praktis
Kasus 1: Form kecil
Kalau state hanya dipakai di satu form, tetap lokal atau naikkan sedikit ke parent. Biasanya tidak perlu Context.
Kasus 2: Tema aplikasi
Kalau banyak komponen perlu tahu mode gelap/terang, Context masuk akal. Ini data global untuk satu subtree UI.
Kasus 3: Sidebar layout
Kalau hanya beberapa komponen dalam layout yang perlu tahu status sidebar, composition atau lifting state ke layout parent sering cukup. Context baru berguna kalau aksesnya benar-benar melewati banyak level.
Kasus 4: User session
Kalau banyak bagian app perlu tahu user aktif, role, atau status login, Context lebih masuk akal karena itu memang shared app state.
Pola Rekomendasi
Urutan berpikir yang aman biasanya begini:
Mulai dari props biasa.
Kalau komponen menjadi terlalu dalam, lihat apakah composition bisa merapikan struktur.
Kalau data memang harus dibaca banyak komponen lintas subtree, baru pakai Context.
Kalau Context mulai membengkak, pecah jadi beberapa context yang lebih kecil.
Jangan jadikan Context tempat semua state.
Ringkasan Cepat
Props: pilihan default.
Composition: dipakai untuk struktur UI yang fleksibel dan reusable.
Context: dipakai untuk shared data yang memang lintas subtree.
Prop drilling: tidak selalu salah; sering hanya tanda bahwa struktur komponen perlu ditata ulang.
Global state kecil yang dibesarkan terlalu dini: sering lebih mahal daripada problem yang ingin diselesaikan.