Jetpack Compose: Thinking in Composables
Compose replaces XML layouts with declarative Kotlin code. The mental model shift is the hardest part.
Key Insights
- Composables are functions, not objects — think transformation, not mutation
- State hoisting separates what to display from how to manage state
- remember and rememberSaveable handle different lifecycle scopes
State Hoisting Pattern
@Composable
fun CounterScreen() {
var count by remember { mutableStateOf(0) }
Counter(count = count, onIncrement = { count++ })
}
@Composable
fun Counter(count: Int, onIncrement: () -> Unit) {
Column {
Text("Count: $count")
Button(onClick = onIncrement) { Text("Increment") }
}
}
Side Effects
@Composable
fun UserScreen(userId: String) {
var user by remember { mutableStateOf<User?>(null) }
LaunchedEffect(userId) {
user = api.fetchUser(userId)
}
user?.let { UserCard(it) }
}
Lists with LazyColumn
LazyColumn {
items(users, key = { it.id }) { user ->
UserRow(user)
}
}