Episode ini membedah jantung Compose: state dan recomposition. Kalian akan menguasai remember, mutableStateOf, state hoisting, integrasi ViewModel dengan StateFlow, serta snapshotFlow dan derivedStateOf untuk mengelola aliran data di UI.

Semua yang kalian pelajari sejauh ini bermuara pada satu konsep: state. UI di Compose adalah fungsi dari state — jadi cara kalian menyimpan, mengubah, dan mengalirkan state menentukan kualitas aplikasi. Episode 5 membedah konsep ini sampai ke akarnya.
Di episode 2 kalian melihat remember dan mutableStateOf sekilas. Sekarang waktunya memahaminya secara menyeluruh, plus dua API yang sering menimbulkan kebingungan: snapshotFlow dan derivedStateOf.
Episode 5 ini meliputi dasar state, state hoisting, integrasi ViewModel, serta snapshot dan derived state.
mutableStateOf membungkus nilai menjadi observable, dan remember menjaga nilainya bertahan antar recomposition. Tanpa remember, nilai akan direset setiap komposisi:
@Composable
fun FormKomentar() {
var nama by remember { mutableStateOf("") }
OutlinedTextField(
value = nama,
onValueChange = { nama = it },
label = { Text("Nama") }
)
}var nama by remember { mutableStateOf("") } memakai delegasi by sehingga pembacaan dan penulisan otomatis terhubung ke snapshot. Setiap nama berubah, composable yang membaca variabel ini direkomposisi.
remember hilang saat Activity di-recreate — misalnya rotasi layar. Untuk state yang harus bertahan, gunakan rememberSaveable, yang menyimpan nilai lewat Bundle:
@Composable
fun Pencarian() {
var query by rememberSaveable { mutableStateOf("") }
OutlinedTextField(
value = query,
onValueChange = { query = it },
placeholder = { Text("Cari...") }
)
}rememberSaveable { mutableStateOf("") } mempertahankan nilai melewati configuration change. Episode 11 akan membahas state restoration lebih dalam.
State hoisting adalah praktik memindahkan state ke composable yang lebih tinggi sehingga menjadi stateless dan dapat dipakai ulang. Pola umum: state naik, event turun.
@Composable
fun LoginScreen() {
var email by remember { mutableStateOf("") }
LoginForm(email = email, onEmailChange = { email = it })
}
@Composable
fun LoginForm(email: String, onEmailChange: (String) -> Unit) {
OutlinedTextField(
value = email,
onValueChange = onEmailChange,
label = { Text("Email") }
)
}LoginForm menerima nilai dan callback, tidak menyimpan state sendiri. Konsekuensinya LoginForm bisa diuji, di-preview, dan dipakai ulang di konteks berbeda. Aturan praktis: composable stateless lebih mudah dipelihara.
ViewModel menyimpan state yang bertahan dari configuration change dan memisahkan UI dari logika bisnis. Pola modern: ViewModel mengekspos StateFlow, dan UI men-collect-nya:
class ProfilViewModel : ViewModel() {
private val _nama = MutableStateFlow("Anonim")
val nama: StateFlow<String> = _nama.asStateFlow()
fun perbaruiNama(namaBaru: String) {
_nama.value = namaBaru
}
}
@Composable
fun ProfilScreen(viewModel: ProfilViewModel) {
val nama by viewModel.nama.collectAsState()
Text(nama)
}collectAsState() mengubah StateFlow menjadi state Compose: setiap nilai baru memicu recomposition. Menggabungkan ViewModel, StateFlow, dan Compose adalah fondasi arsitektur MVVM yang akan dibahas di episode 20. Logika state-nya bisa diuji tanpa emulator — jalankan ./gradlew :app:testDebugUnitTest untuk menjalankan unit test pada ViewModel.
derivedStateOf menghitung nilai turunan dari state lain dan hanya membangkitkan recomposition ketika hasil turunannya benar-benar berubah:
val daftarTugas by remember { mutableStateOf<List<Tugas>>(emptyList()) }
val selesaiCount by remember {
derivedStateOf { daftarTugas.count { it.selesai } }
}derivedStateOf berguna saat transformasi mahal dan hasilnya berubah jarang — pola performa yang akan diperdalam di episode 15. Contoh lain: menampilkan status scroll ke atas hanya setelah posisi tertentu.
snapshotFlow adalah kebalikan arah: mengubah snapshot state Compose menjadi aliran data Kotlin yang bisa di-collect dan di-transformasi dengan operator Flow:
snapshotFlow { sliderValue }.distinctUntilChanged()
.debounce(300)
.collect { nilai ->
onNilaiDebounce(nilai)
}snapshotFlow { sliderValue } menangkap perubahan state, distinctUntilChanged membuang duplikat, dan debounce(300) menunda pemrosesan. Pemakaian dengan efek samping (LaunchedEffect) akan dibahas di episode 10.
Episode 5 membuka jantung Compose: state dan recomposition. Kalian menguasai remember dan mutableStateOf, rememberSaveable untuk configuration change, state hoisting dengan pola state naik event turun, integrasi ViewModel lewat StateFlow dan collectAsState, serta derivedStateOf dan snapshotFlow untuk mengelola turunan dan aliran data.
Inti yang harus dibawa pulang:
remember menjaga state antar recomposition, rememberSaveable melewati recreation.collectAsState adalah pola MVVM standar.derivedStateOf menghitung turunan yang jarang berubah.snapshotFlow mengubah state Compose menjadi Flow Kotlin.Di episode 6 selanjutnya kita akan membahas theming dan Material Design — MaterialTheme, typography, colors, dan shapes, dukungan light dan dark theme, dynamic color di Android 12, serta cara membangun design system sendiri.