Reputation: 33
I have a LaunchedEffect in my Composable like following. I want it to trigger every time a new instance of ViewEffect.Action
is set in the viewEffect
LiveData.
val viewEffect by viewModel.viewEffect.observeAsState()
when (viewEffect) {
is ViewEffect.Action -> {
LaunchedEffect(viewEffect) {
viewModel.takeAction(viewEffect as ViewEffect.Action)
}
}
}
This results in 2 odd behaviors:
When I navigate to a different Composable using NavHostController and come back, the LaunchedEffect is executed again even though viewEffect
hasn't changed.
Even weirder, after coming back to the original Composable, after the first execution, the LaunchedEffect will never trigger again, even if the value of viewEffect
changes. This behavior is only seen after navigating away and back.
(More context) ViewEffect.Action has a custom equals method which compares by reference to allow it to fire multiple times with same data values:
data class Action(val info: Info) : ViewEffect() {
// Override equals so that LaunchedEffect compares keys by reference
// when deciding whether to launch
override fun equals(other: Any?): Boolean {
return this === other
}
override fun hashCode(): Int {
return info.hashCode()
}
}
I tried clearing the value of viewEffect
LiveData before navigating away from the Composable, and this fixed the first issue, but the second one still persisted. I'm also hoping there is a better solution than this.
Upvotes: 1
Views: 1460
Reputation: 1305
When you navigate to a different Composable using NavHostController, your LaunchedEffect leaves the composition and a coroutine with the block of code passed as a parameter will be cancelled. When you come back, the LaunchedEffect is executed again even though key(s) hasn't changed and that's the way it's meant to be.
So 1st oddity is normal behavior.
The 2nd oddity may be caused by the fact that the LaunchedEffect is wrapped in when
block, try this way:
LaunchedEffect(viewEffect) {
when (viewEffect) {
is ViewEffect.Action -> {
viewModel.takeAction(viewEffect as ViewEffect.Action)
}
}
}
Upvotes: 0