ReactJS #21: useContext
Berbagi Data ke Semua Komponen Tanpa Ribet
(Seperti Pengeras Suara)
Halo, penyebar informasi! 📢
Pernahkah kamu melihat seseorang berteriak menggunakan pengeras suara (megaphone)? Suaranya bisa didengar oleh banyak orang tanpa harus mendatangi satu per satu. Di React, kita juga punya alat seperti pengeras suara untuk berbagi data ke banyak komponen tanpa harus mengirim props secara manual melalui setiap tingkatan. Alat itu bernama useContext!
🧐 Masalah: Prop Drilling
Sebelum useContext, jika kita ingin mengirim data dari komponen paling atas ke komponen yang sangat dalam, kita harus mengirim props melalui komponen perantara yang mungkin tidak membutuhkan data tersebut. Ini disebut prop drilling. Ibaratnya, kamu harus menitipkan pesan melalui banyak teman, padahal teman-teman itu tidak perlu tahu isi pesannya.
Contoh: Komponen App punya data user, dan komponen Profil di dalam Sidebar di dalam Dashboard membutuhkan data itu. Maka App kirim ke Dashboard, Dashboard kirim ke Sidebar, Sidebar kirim ke Profil. Ribet!
📢 Solusi: useContext
Context memungkinkan kita membuat "pengeras suara" global untuk data tertentu. Data bisa diakses oleh komponen mana pun yang "mendengarkan" context itu, tanpa perlu props. Ada 3 langkah utama:
- Membuat Context dengan
createContext(). - Menyediakan Context dengan
Providerdi komponen induk. - Menggunakan Context dengan
useContext()di komponen anak.
🛠️ Langkah 1: Membuat Context
Biasanya kita buat file terpisah untuk context, misal src/context/ThemeContext.js:
createContext() menghasilkan object yang berisi Provider dan Consumer. Kita akan pakai Provider nanti.
🔊 Langkah 2: Menyediakan Context (Provider)
Di komponen induk (misal App.js), kita bungkus komponen anak dengan Provider dan beri nilai (value). Nilai ini bisa berupa apa saja: string, number, object, bahkan state.
Semua komponen di dalam Provider bisa mengakses nilai { theme, toggleTheme }.
📣 Langkah 3: Menggunakan Context (useContext)
Di komponen anak mana pun (sedalam apa pun), kita bisa gunakan useContext untuk mendapatkan nilai dari context terdekat.
Buat komponen Toolbar.js:
Buat komponen Button.js (lebih dalam):
Lihat! Komponen Button bisa langsung mengakses toggleTheme dan theme tanpa props dari Toolbar.
🎨 Demo Simulasi Tema
Tema saat ini: light
Klik tombol di atas akan mengubah latar belakang (simulasi).
🧩 Contoh Lain: Data Pengguna (User Context)
Context sangat cocok untuk data yang digunakan banyak komponen, seperti data pengguna yang login. Buat UserContext.js:
Di App.js:
Di Profile.js (komponen dalam):
Tanpa props, komponen Profile bisa menampilkan data user.
⚠️ Hal Penting
- Jangan gunakan context untuk semua data. Context bagus untuk data global seperti tema, user, bahasa. Untuk data lokal, tetap gunakan props atau state biasa.
- Provider bisa bersarang. Jika ada beberapa context, kita bisa membungkus berlapis.
- Jika nilai context sering berubah, semua komponen yang menggunakan context akan re-render. Untuk mengoptimalkan, pisahkan context yang jarang berubah dan sering berubah.
🧪 Latihan: Keranjang Belanja dengan Context
Buat aplikasi keranjang belanja sederhana menggunakan context. Fitur:
- Context
CartContextmenyimpan daftar item di keranjang dan fungsi untuk menambah/menghapus. - Komponen
ProductListmenampilkan daftar produk (bisa hardcoded) dan tombol "Tambah ke Keranjang". - Komponen
Cartmenampilkan isi keranjang dan total harga. - Gunakan
useContextdi kedua komponen untuk mengakses state dan fungsi.
Petunjuk: Buat context dengan nilai { cart, addToCart, removeFromCart }.
addToCart bisa menambah item baru. removeFromCart bisa menyaring berdasarkan id.
🔍 Perbandingan Props vs Context
| Props | Context |
|---|---|
| Data dikirim manual melalui setiap tingkatan | Data tersedia untuk semua komponen di dalam Provider |
| Cocok untuk data lokal antar komponen dekat | Cocok untuk data global yang digunakan banyak komponen |
| Mudah dilacak alur datanya | Bisa membuat alur data kurang jelas jika terlalu banyak context |
🚀 Kesimpulan
- useContext adalah solusi untuk menghindari prop drilling.
- Buat context dengan
createContext(), sediakan nilai denganProvider, gunakan denganuseContext(). - Context cocok untuk data global seperti tema, user, keranjang belanja.
- Jangan berlebihan menggunakan context; pertimbangkan skala dan frekuensi perubahan data.
Di artikel selanjutnya kita akan belajar tentang useReducer, alternatif useState untuk state yang kompleks. Sampai jumpa!