Berbagi State di React (Lifting Up)
Bagaimana cara membuat beberapa komponen anak bisa mengakses dan mengubah data yang sama? Pelajari pola 'Lifting State Up' di ReactJS, di mana state dipindahkan ke parent bersama terdekat.
Biar Komponen Bisa "Ngobrol" Soal Data: Jurus Lifting State Up di React!
Udah jago kan bikin komponen yang punya data internal (state) sendiri pake useState
? Dan udah bisa juga ngasih "bekal" (props) dari parent ke child? Keren!
Tapi, gimana kalau ada skenario kayak gini:
- Kamu punya dua komponen input field, dan kamu pengen nilai di satu input field itu bisa ngaruh atau dibaca sama input field lainnya.
- Atau, kamu punya daftar item, dan ada komponen lain (misalnya, di atas daftar itu) yang pengen nampilin jumlah total item di daftar itu.
- Intinya, ada dua atau lebih komponen "saudara" (sibling) atau komponen yang beda jalur di pohon komponen, tapi mereka butuh "ngobrolin" atau make data (state) yang sama.
Kalau state-nya disimpen di masing-masing komponen itu sendiri, mereka jadi punya "catatan" masing-masing yang gak sinkron. Nah, di sinilah pola Lifting State Up (Mengangkat State ke Atas) jadi solusi elegan di React!
Masalahnya: State yang Terisolasi
Bayangin kita punya dua komponen: satu buat ngubah suhu dalam Celcius, satu lagi buat nampilin apakah air bakal mendidih atau beku berdasarkan suhu itu.
// File: InputSuhu.jsx (Contoh Konseptual Awal)
// JANGAN DITIRU DULU, INI BELUM BENER BUAT BERBAGI STATE
import React, { useState } from 'react';
function InputSuhuCelcius() {
const [celcius, setCelcius] = useState(0);
return (
<div>
<label>Masukkan Suhu (Celcius): </label>
<input
type="number"
value={celcius}
onChange={(e) => setCelcius(parseFloat(e.target.value))}
/>
</div>
);
}
function StatusAir() {
// Gimana StatusAir bisa tau nilai 'celcius' dari InputSuhuCelcius?
// Kalau 'celcius' itu state lokal di InputSuhuCelcius, StatusAir gak bisa akses!
let status = "Air berbentuk cair.";
// if (celcius >= 100) status = "Air mendidih!";
// if (celcius <= 0) status = "Air membeku!";
return <p>Status Air: {status}</p>;
}
function AplikasiSuhu() {
return (
<div>
<InputSuhuCelcius />
<StatusAir />
</div>
);
}
Di sini, StatusAir
gak bisa "liat" nilai celcius
yang ada di InputSuhuCelcius
karena state itu lokal buat InputSuhuCelcius
.
Solusinya: "Angkat" State-nya ke Parent Bersama Terdekat!
Pola Lifting State Up ngajarin kita: Kalau ada beberapa komponen yang butuh ngakses atau ngubah state yang sama, pindahin state itu ke komponen parent (induk) terdekat yang jadi "nenek moyang bersama" dari semua komponen yang butuh state itu.
Setelah state-nya ada di parent:
- Parent bakal ngirim nilai state itu sebagai prop ke semua anak yang butuh ngebacanya.
- Kalau ada anak yang butuh ngubah state itu, parent bakal ngirim fungsi (sebagai prop juga) ke anak itu. Fungsi ini, pas dipanggil sama si anak, sebenernya bakal ngejalanin logika buat ngupdate state yang ada di parent.
Jadi, parent yang jadi "pemegang kendali" state-nya, anak-anak cuma "nerima" dan "ngasih tau" kalau ada perubahan.
Contoh Penerapan Lifting State Up buat Aplikasi Suhu:
Komponen parent bersamanya di sini adalah AplikasiSuhu
. Jadi, kita pindahin state celcius
dan fungsi buat ngubahnya ke AplikasiSuhu
.
import React, { useState } from 'react';
// Komponen Anak 1: InputSuhuCelcius (sekarang nerima suhu dan fungsi ubah dari props)
function InputSuhuCelcius(props) {
const handleChange = (e) => {
props.onSuhuChange(e.target.value); // Panggil fungsi dari parent pas input berubah
};
return (
<fieldset>
<legend>Masukkan Suhu dalam Celcius:</legend>
<input
type="number"
value={props.suhu} // Nilai input dikontrol prop dari parent
onChange={handleChange}
/>
</fieldset>
);
}
// Komponen Anak 2: StatusAir (nerima suhu dari props)
function StatusAir(props) {
const celcius = parseFloat(props.suhu); // Pastikan suhu itu angka
let status = "Air berbentuk cair.";
if (isNaN(celcius)) {
status = "Masukkan angka suhu yang valid.";
} else if (celcius >= 100) {
status = "Air akan MENDIDIH!";
} else if (celcius <= 0) {
status = "Air akan MEMBEKU!";
}
return <p>Status Air: {status}</p>;
}
// Komponen Parent: AplikasiSuhu (sekarang dia yang punya state)
function AplikasiSuhu() {
const [suhu, setSuhu] = useState(''); // State 'suhu' ada di sini, nilai awal string kosong
const handleSuhuCelciusChange = (nilaiSuhuBaru) => {
setSuhu(nilaiSuhuBaru); // Fungsi buat ngupdate state 'suhu'
};
// Kita juga bisa bikin konversi ke Fahrenheit di sini
const fahrenheit = suhu === '' ? '' : (parseFloat(suhu) * 9/5) + 32;
return (
<div>
<h1>Kalkulator Suhu Sederhana</h1>
{/* Kirim state 'suhu' dan fungsi 'handleSuhuCelciusChange' sebagai props */}
<InputSuhuCelcius
suhu={suhu}
onSuhuChange={handleSuhuCelciusChange}
/>
{/* Kirim state 'suhu' sebagai prop */}
<StatusAir suhu={suhu} />
{/* Contoh nambahin input Fahrenheit yang juga dikontrol dari state yg sama (di-lift) */}
<InputSuhuFahrenheit
suhu={fahrenheit}
onSuhuChange={(nilaiFahrenheitBaru) => {
// Konversi balik ke Celcius sebelum ngeset state 'suhu'
if (nilaiFahrenheitBaru === '') {
setSuhu('');
} else {
setSuhu( (parseFloat(nilaiFahrenheitBaru) - 32) * 5/9 );
}
}}
/>
</div>
);
}
// Komponen Anak 3: InputSuhuFahrenheit (mirip InputSuhuCelcius)
function InputSuhuFahrenheit(props) {
const handleChange = (e) => {
props.onSuhuChange(e.target.value);
};
return (
<fieldset style={{marginTop: '10px'}}>
<legend>Masukkan Suhu dalam Fahrenheit:</legend>
<input
type="number"
value={props.suhu}
onChange={handleChange}
/>
</fieldset>
);
}
export default AplikasiSuhu;
Bedah Alur Lifting State Up di Contoh Suhu:
- State
suhu
dan fungsisetSuhu
sekarang ada diAplikasiSuhu
(parent). AplikasiSuhu
ngirimsuhu
(sebagai propsuhu
) danhandleSuhuCelciusChange
(sebagai proponSuhuChange
) keInputSuhuCelcius
.- Pas pengguna ngetik di
InputSuhuCelcius
, eventonChange
-nya manggilhandleChange
di dalemInputSuhuCelcius
. handleChange
diInputSuhuCelcius
ini manggil fungsiprops.onSuhuChange
(yang sebenernya adalahhandleSuhuCelciusChange
dariAplikasiSuhu
) sambil ngasih nilai input baru.handleSuhuCelciusChange
diAplikasiSuhu
dijalanin, dan dia ngupdate statesuhu
pakesetSuhu()
.- Karena state
suhu
diAplikasiSuhu
berubah,AplikasiSuhu
nge-re-render. - Pas re-render,
AplikasiSuhu
ngirim nilaisuhu
yang baru sebagai prop keInputSuhuCelcius
(jadi input field-nya ke-update) DAN keStatusAir
(jadi status airnya juga ke-update). - Hal yang sama berlaku buat
InputSuhuFahrenheit
, dia juga ngontrol statesuhu
yang sama diAplikasiSuhu
lewat fungsi callback yang dikonversi.
Sekarang, semua komponen yang butuh data suhu itu jadi sinkron karena "sumber kebenarannya" (suhu
) cuma ada satu, yaitu di parent bersama mereka (AplikasiSuhu
).
Kenapa Lifting State Up Itu Bagus?
- Single Source of Truth: Data yang sama cuma disimpen di satu tempat. Ini ngurangin risiko data jadi gak konsisten antar komponen.
- Alur Data Lebih Jelas: Data ngalir dari atas (parent) ke bawah (child) lewat props. Perubahan data (state) juga dikontrol sama parent lewat fungsi callback yang dikirim ke child. Ini bikin debug jadi lebih gampang.
- Komponen Child Jadi Lebih "Dumb" (Bodoh) dan Reusable: Komponen child (kayak
InputSuhuCelcius
atauStatusAir
) jadi lebih fokus nampilin UI berdasarkan props yang dia terima, dan "ngasih tau" parent kalau ada aksi. Dia gak perlu pusing ngurusin state yang kompleks atau logika bisnis yang rumit. Ini bikin mereka lebih gampang dipake ulang di tempat lain.
Kapan Kamu Perlu "Ngangkat" State?
- Setiap kali kamu sadar ada beberapa komponen yang butuh ngakses data yang sama.
- Atau kalau perubahan state di satu komponen perlu ngaruh ke komponen lain yang bukan anak langsungnya.
- Cari "nenek moyang bersama" terdekat dari komponen-komponen itu, terus pindahin state-nya ke situ.
Lifting state up ini adalah salah satu pola paling fundamental dan penting buat ngelola state di aplikasi React yang mulai kompleks. Emang awalnya mungkin kerasa agak muter-muter karena harus ngoper fungsi sebagai prop, tapi begitu kamu "klik", ini bakal jadi jurus andalanmu!
Dengan props, state, dan sekarang lifting state up, kamu udah punya alat yang cukup buat bikin komponen React yang bener-bener dinamis, interaktif, dan bisa "ngobrol" satu sama lain. Ini adalah dasar buat ngebangun aplikasi React yang lebih gede dan canggih.
Kuis Berbagi State di React (Lifting State Up)
Pertanyaan 1 dari 4
Kapan Anda biasanya perlu menerapkan pola 'Lifting State Up' dalam aplikasi React?