Learn Jetpack Compose - State & Recomposition
Episode 5 of 23

Learn Jetpack Compose - State & Recomposition

This episode dissects the heart of Compose: state and recomposition. You'll master remember, mutableStateOf, state hoisting, ViewModel integration with StateFlow, and snapshotFlow and derivedStateOf for managing data flow in the UI.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Everything you've learned so far boils down to one concept: state. UI in Compose is a function of state — so the way you store, change, and flow state determines the quality of your application. Episode 5 dissects this concept down to its roots.

In episode 2 you saw remember and mutableStateOf in passing. Now it's time to understand them thoroughly, plus two APIs that often cause confusion: snapshotFlow and derivedStateOf.

Episode 5 covers the basics of state, state hoisting, ViewModel integration, and snapshot and derived state.

State Basics: remember and mutableStateOf

State That Survives

mutableStateOf wraps a value into an observable, and remember keeps the value surviving across recompositions. Without remember, the value would be reset on every composition:

Kotlinremember and mutableStateOf
@Composable
fun FormKomentar() {
    var nama by remember { mutableStateOf("") }
 
    OutlinedTextField(
        value = nama,
        onValueChange = { nama = it },
        label = { Text("Nama") }
    )
}

var nama by remember { mutableStateOf("") } uses the by delegate so reads and writes are automatically connected to the snapshot. Every time nama changes, the composables that read this variable are recomposed.

rememberSaveable: Surviving Configuration Changes

remember is lost when the Activity is recreated — for example on screen rotation. For state that must survive, use rememberSaveable, which saves the value through a Bundle:

KotlinrememberSaveable
@Composable
fun Pencarian() {
    var query by rememberSaveable { mutableStateOf("") }
    OutlinedTextField(
        value = query,
        onValueChange = { query = it },
        placeholder = { Text("Cari...") }
    )
}

rememberSaveable { mutableStateOf("") } keeps the value across configuration changes. Episode 11 will cover state restoration in more depth.

State Hoisting

Lifting State Up

State hoisting is the practice of moving state to a higher composable so it becomes stateless and reusable. The common pattern: state goes up, events come down.

KotlinState hoisting
@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 receives a value and a callback and doesn't store state itself. As a result, LoginForm can be tested, previewed, and reused in different contexts. A good rule of thumb: stateless composables are easier to maintain.

ViewModel Integration

ViewModel and StateFlow

A ViewModel stores state that survives configuration changes and separates the UI from business logic. The modern pattern: the ViewModel exposes a StateFlow, and the UI collects it:

KotlinViewModel with StateFlow
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() turns a StateFlow into Compose state: every new value triggers recomposition. Combining ViewModel, StateFlow, and Compose is the foundation of the MVVM architecture that will be discussed in episode 20. Its state logic can be tested without an emulator — run ./gradlew :app:testDebugUnitTest to run unit tests on the ViewModel.

snapshotFlow and derivedStateOf

derivedStateOf for Derived Values

derivedStateOf computes a value derived from other state and only triggers recomposition when the derived result actually changes:

KotlinderivedStateOf
val daftarTugas by remember { mutableStateOf<List<Tugas>>(emptyList()) }
val selesaiCount by remember {
    derivedStateOf { daftarTugas.count { it.selesai } }
}

derivedStateOf is useful when the transformation is expensive and the result changes rarely — a performance pattern that will be deepened in episode 15. Another example: showing a scroll-to-top status only after a certain position.

snapshotFlow: State Becomes a Flow

snapshotFlow is the reverse direction: it turns Compose snapshot state into a Kotlin data stream that can be collected and transformed with Flow operators:

KotlinsnapshotFlow
snapshotFlow { sliderValue }.distinctUntilChanged()
    .debounce(300)
    .collect { nilai ->
        onNilaiDebounce(nilai)
    }

snapshotFlow { sliderValue } captures state changes, distinctUntilChanged drops duplicates, and debounce(300) delays processing. Using it with side effects (LaunchedEffect) will be discussed in episode 10.

Closing

Episode 5 unlocked the heart of Compose: state and recomposition. You mastered remember and mutableStateOf, rememberSaveable for configuration changes, state hoisting with the state-up/events-down pattern, ViewModel integration through StateFlow and collectAsState, and derivedStateOf and snapshotFlow for managing derived values and data flows.

Key takeaways:

  • remember keeps state across recompositions; rememberSaveable survives recreation.
  • State hoisting: keep state above, pass values and events down.
  • ViewModel with StateFlow and collectAsState is the standard MVVM pattern.
  • derivedStateOf computes derivations that change rarely.
  • snapshotFlow turns Compose state into a Kotlin Flow.
  • Stateless composables are easier to test and reuse.

In episode 6 we will discuss theming and Material Design — MaterialTheme, typography, colors, and shapes, light and dark theme support, dynamic color on Android 12, and how to build your own design system.

Learn Jetpack Compose - State & Recomposition | Learn Jetpack Compose