Interview frequency: …
Short answer
LaunchedEffect launches a coroutine to perform an asynchronous task when a key changes; DisposableEffect runs code while providing mandatory cleanup (onDispose) when the component leaves.
Explanation
A side effect is any change in the app's state that happens outside the scope of the composable function. LaunchedEffect runs the code in a CoroutineScope tied to the component's lifecycle and is cancelled automatically if it leaves the screen or the keys change. DisposableEffect is used to register listeners (observers/callbacks) that require an explicit unsubscribe inside an onDispose block.
Code example
// LaunchedEffect: Call the API when changes userId
LaunchedEffect(userId) {
viewModel.loadUserDetails(userId)
}
// DisposableEffect: Register and remove a listener
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event -> ... }
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}Common mistakes
- Launching a coroutine or making network calls directly in the body of a composable function without using a side-effect API.
- Forgetting to add the appropriate key to LaunchedEffect(key), which prevents it from restarting when the inputs change.