Which side-effect handler for a one-time coroutine on composition entry?

Tests Compose side-effect API boundaries. Answer: LaunchedEffect(Unit); it runs once and auto-cancels on exit. Contrast with rememberCoroutineScope for user-triggered callbacks. Red flag: picking SideEffect or rememberCoroutineScope and missing cancellation.
WHAT THIS TESTS: Your ability to select the correct Compose side-effect API based on lifecycle and execution model. The interviewer wants to see that you understand the difference between coroutine-based effects tied to composition, synchronous recompositions, and user-triggered scope launching. Specifically they are checking if you know which API auto-manages cancellation and scope creation.
A GOOD ANSWER COVERS: First, name LaunchedEffect and pass a constant key such as Unit or true so the block executes exactly once when the composable enters composition. Second, explain that LaunchedEffect creates a coroutine scoped to the composition which is automatically cancelled if the composable leaves the composition, preventing leaks and stale work. Third, contrast this with rememberCoroutineScope, which is intended for event handlers and user-triggered actions like button clicks where you need a scope in a callback; it does not auto-run on entry and requires manual lifecycle awareness. Fourth, mention SideEffect only to exclude it, noting it runs synchronously on every successful recomposition and is not a coroutine builder. Fifth, optionally note DisposableEffect is for setup and teardown of resources like listeners, not for one-shot async fetches.
COMMON WRONG ANSWERS: Picking rememberCoroutineScope and wrapping the call in a remembered flag or LaunchedEffect-like logic shows you are forcing an API meant for callbacks into a lifecycle role. Using SideEffect demonstrates confusion between synchronous recompositions and asynchronous coroutine work. Forgetting the key parameter or using a changing key like a state object means the effect restarts on every update, violating the one-time requirement. Launching a bare GlobalScope or lifecycleScope inside a composable without tying it to composition exit is a serious red flag for leaks.
LIKELY FOLLOW-UPS: How would you handle the fetch being restarted if the user rotates the screen? The follow-up tests whether you mention ViewModel, rememberSaveable, or configuration change handling outside of LaunchedEffect. What if you need to cancel and restart when a parameter changes? Then you would use LaunchedEffect(key) with the parameter as the key. When would you use rememberCoroutineScope instead? When a user clicks a button and you need to launch a snackbar or animation from a callback outside of the composition flow.
ONE CONCRETE EXAMPLE: You have a ProfileScreen composable that needs to load user data from a network endpoint when the screen appears. Inside ProfileScreen you write LaunchedEffect(Unit) { viewModel.loadProfile() }. Because Unit never changes, this triggers once on entry. If the user navigates away before the request completes, the coroutine is cancelled automatically. You do not write val scope = rememberCoroutineScope() followed by scope.launch { ... } at the top level of the composable because that would fire immediately during composition without lifecycle-aware cancellation semantics and would be the wrong pattern for an automatic entry effect.
Source: developer.android.com
Read the original → developer.android.com
- #android
- #jetpack-compose
- #side-effects
- #coroutines
- #intermediate
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.