Question #383MediumNative Android

What is recomposition in Jetpack Compose?

#jetpack-compose#recomposition#state

Answer

Overview

Recomposition is when Compose re-executes composable functions when state changes.


How It Works

kotlin
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    
    Column {
        Text("Count: $count") // Recomposes when count changes
        Button(onClick = { count++ }) {
            Text("Increment")
        }
    }
}

Recomposition Triggers

State Changes

kotlin
@Composable
fun Example() {
    var name by remember { mutableStateOf("Alice") }
    
    Text(name) // Recomposes when name changes
    Button(onClick = { name = "Bob" }) {
        Text("Change")
    }
}

LiveData/StateFlow

kotlin
@Composable
fun UserProfile(viewModel: UserViewModel) {
    val user by viewModel.user.collectAsState()
    
    Text(user.name) // Recomposes when user changes
}

Recomposition Scope

Only affected composables recompose:

kotlin
@Composable
fun App() {
    var count by remember { mutableStateOf(0) }
    
    Column {
        Text("Static text") // Never recomposes
        Text("Count: $count") // Recomposes on count change
        Button(onClick = { count++ }) {
            Text("Click") // Never recomposes
        }
    }
}

Optimization

skip (Automatic)

kotlin
@Composable
fun StableComponent(user: User) {
    // If user hasn't changed, this won't recompose
    Text(user.name)
}

remember

kotlin
@Composable
fun ExpensiveComponent() {
    val expensiveValue = remember {
        computeExpensive() // Only computed once
    }
    Text(expensiveValue)
}

derivedStateOf

kotlin
@Composable
fun FilteredList(items: List<Item>, query: String) {
    val filtered = remember(items, query) {
        derivedStateOf {
            items.filter { it.name.contains(query) }
        }
    }
    // Only recomposes when filtered changes
}

Important Rules

  1. Composables can execute in any order
  2. Composables can run in parallel
  3. Recomposition skips as much as possible
  4. Recomposition is optimistic (may be cancelled)

Side Effects Warning

kotlin
// ❌ BAD - side effect in composable
@Composable
fun BadExample() {
    var count = 0 // Wrong! Resets on recomposition
    Text("$count")
}

// ✅ GOOD - use remember
@Composable
fun GoodExample() {
    var count by remember { mutableStateOf(0) }
    Text("$count")
}

Key Point: Recomposition is automatic, efficient, and scope-limited.