I want to show some data and simulate loading. For this reason I use LaunchedEffect on the first screen. It works fine, but when I add navigation, LaunchedEffect launch twice.
Navigation: First (LaunchedEffect) -> Second -> Back to first (LaunchedEffect launch again)
I expect that when I return to the first screen LaunchedEffect won't launch and I will immediately see the data.
Sample of LaunchedEffect:
@Composable
fun FirstScreen(...) {
...
LaunchedEffect(Unit) {
state = State.Loading
delay(2_000L)
state = State.Success(...)
}
}
Sample of navigation:
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = FIRST_ROTE
) {
composable(FIRST_ROTE) { FirstScreen(...) }
composable(SECOND_ROTE) { SecondScreen(...) }
}
CodePudding user response:
See what the documentation says
To call suspend functions safely from inside a composable, use the
LaunchedEffect
composable. WhenLaunchedEffect
enters the Composition, it launches a coroutine with the block of code passed as a parameter. The coroutine will be cancelled ifLaunchedEffect
leaves the composition. IfLaunchedEffect
is recomposed with different keys, the existing coroutine will be cancelled and the new suspend function will be launched in a new coroutine.
When you navigate to another screen, the composable is removed from the composition (which means it is not drawn). This is why the LaunchedEffect
is executed again.
You can control this execution using the state in view model. Something like:
@Composable
fun FirstScreen(vm: YourViewModel) {
LaunchedEffect(Unit) {
if (vm.someFlag == true) {
vm.someFlag = false
state = State.Loading
delay(2_000L)
state = State.Success(...)
}
}
}