State & Recomposition
What is state?
“State” is any data that can change over time and affects the UI: a counter, the text in a field, a loading flag. In Compose, when state changes, the affected composables run again to reflect the new value. This re-running is called recomposition.
Creating state
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Column {
Text("Count: $count")
Button(onClick = { count++ }) {
Text("Add one")
}
}
}
Three things are happening:
mutableStateOf(0)creates an observable value — Compose watches it.remember { }keeps that value across recompositions (without it, the count would reset to 0 every redraw).byis a delegate so you can read/writecountdirectly instead ofcount.value.
Tapping the button changes count → the Text recomposes → the new number appears. You never told the Text to update; it just did.
remember vs rememberSaveable
remember survives recomposition but is lost on a configuration change (like rotation). rememberSaveable also survives rotation by saving the value automatically.
var name by rememberSaveable { mutableStateOf("") } // kept across rotation
State only redraws what reads it
Compose is smart: only composables that actually read a piece of state recompose when it changes. This makes it efficient even on complex screens — structure your UI so state is read as low in the tree as possible.
Common mistakes
- Forgetting
remember— the value resets on every recomposition. - Creating state with plain
var count = 0— Compose won’t observe it; usemutableStateOf. - Using
rememberfor data that should survive rotation — userememberSaveableor a ViewModel.
Summary: State is observable data (mutableStateOf) kept across redraws withremember(orrememberSaveablefor rotation). Changing state triggers recomposition, which updates only the UI that reads it.