I have a query regarding Collecting ViewState outside LaunchedEffect when implementing MVI with Jetpack compose.
I've noticed that when I collect the ViewModel's state outside a LaunchedEffect, it seems to work, but I'm concerned about potential issues like creating multiple collectors on recomposition. Can someone clarify if collecting ViewState outside a LaunchedEffect is safe or if it might lead to unintended behavior?
Is it recommended to use collectAsState() outside LaunchedEffect?
@Composable
fun ListScreenContent(callback: (countryName: String) -> Unit) {
val viewModel: ListViewModel = hiltViewModel()
val listViewState by viewModel.viewState.collectAsState()
LaunchedEffect(Unit) {
viewModel.sideEffect.collect {
if (it is ListContract.SideEffect.NavigateToDetails) {
val countryName = it.countryName
callback(countryName)
}
}
}
ListViewStateComposable(viewState = listViewState, callback = { name ->
...
})
}
ViewModel
val viewState: StateFlow<ListContract.ViewState>
get() = _state.asStateFlow()
val sideEffect: SharedFlow<ListContract.SideEffect>
get() = _sideEffect.asSharedFlow()
This is call produceState which is
And produceState assigns value to
Statewhich is collected insideFlow.collectBasically they are the same thing except when you implement logic inside collect in LaunchedEffect it's called only when you collect a new value but if you put
this out of
LaunchedEffectit will be called every timeListScreenContentis recomposed.