Which one is better to use in ViewModel StateFlow or Compose State
Mozhdeh Nouri Sarani
Android Developer : Kotlin | Mentor | Technical Knowledge Sharing | Team Player
If you already work with compose you face this challenge
Which one we should use in ViewModel? StateFlow or compose State
As you know HotFlow and compose State(mutableStateOf()) are Reactive which means the program reacts to data or event changes instead of requesting information about changes.
When we call stateFlow from ViewModel in a compose function we use the collectAsStateWithLifecycle extension function.
How does it work internally?
collectAsStateWithLifecycle is a composable function that collects values from a flow and represents the latest value as Compose State in a lifecycle-aware manner. Every time a new flow emission occurs, the value of this State object updates.
By default, collectAsStateWithLifecycle uses Lifecycle.State.STARTED to start and stop collecting values from the flow. This occurs when the Lifecycle moves in and out of the target state.
You can move the lifecycle with the minActiveState parameter
@Composable
fun <T> StateFlow<T>.collectAsStateWithLifecycle(
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
context: CoroutineContext = EmptyCoroutineContext
): State<T> = collectAsStateWithLifecycle(
initialValue = this.value,
lifecycle = lifecycleOwner.lifecycle,
minActiveState = minActiveState,
context = context
)
collectAsStateWithLifecycle uses produceState to convert flow to a compose state
@Composable
fun <T> Flow<T>.collectAsStateWithLifecycle(
initialValue: T,
lifecycle: Lifecycle,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
context: CoroutineContext = EmptyCoroutineContext
): State<T> {
return produceState(initialValue, this, lifecycle, minActiveState, context) {
lifecycle.repeatOnLifecycle(minActiveState) {
if (context == EmptyCoroutineContext) {
[email protected] { [email protected] = it }
} else withContext(context) {
[email protected] { [email protected] = it }
}
}
}
} }
}
Now as we know when a user navigates another screen flow stops collecting because of the use lifecycle internally.
领英推荐
Why do we need to use flow instead of compose state inside ViewModel :
Now My question is :
What happens about the Lifecycle when we use compose State ( mutableStateOf() ) in ViewModel?
First, we should check the viewModel lifecycle in the compose
So as the document says: To use a ViewModel in Compose, you can?pass the lifecycleOwner parameter to the ViewModel constructor. The lifecycleOwner will keep track of the lifecycle of the composable and will ensure that the ViewModel is only active when the composable is visible.
For instance :
You can use?navigation, which is perfect for your needs, each route has its own view model scope, which is destroyed as soon as the route is removed from the navigation back stack.
Or you can use DisposableEffect for free viewModel when the screen isn't active anymore...
So if you use compose State in ViewModel don't forget to consider the state lifecycle
Tell me about your idea or your experiences in comment
Principal Software Engineer at Advanced Bionics R&D-Software Engineering
5 个月While the general principle of ViewModel independence from UI is sound, in Compose's reactive paradigm, ViewModels are designed to directly drive UI state. Using State with a private setter offers a more streamlined approach than Flow. Flow requires additional code within Composable components, such as observerAsState, which can make the UI logic less declarative and more procedural. Of course you can combine these two, but Flow is more suitable for Services and Repositories which ViewModel can observe for changes and reflect them for UI
Wireline Log Engineer
1 年Thank you for sharing
Senior Android Engineer @Nesine
1 年Thanks for your effort. It also provides usage advantages such as "map, filter, flatmaplatetest, etc." in the downstream process.
Android Developer | Kotlin, Java | Compose | Swift UI
1 年Great article ? Thank you for sharing ?? ? While Compose has many advantages,?I believe there could be more reasons to use the ViewModel as Flow-based. This approach also would allow us to combine different flows and leverage the power of flow operators more effectively.