Ryan Smith
10/27/2022, 2:03 AMFlow
and Compose
? One of the predominant lessons I've been learning is "make your composables stateless by hoisting". I'm trying to adhere to this by exposing as much state as makes sense through properties on my view models.
For example, my data layer has an in-memory Repository that exposes a collection of items through a Flow
. My view model is meant to collect
that flow as state, and expose that state to my Table
composable to be displayed on the screen. But since collectAsState
is marked as @Composable
I can't call it from my view model. As I see it I could either pass the Flow
directly through my view model to my Table
composable or stick with mutableStateOf
and collect the Flow
internally to the view model and just expose the MutableState
to my Table
.
More generally, though, it feels like the two ideas "state through the view model" and "collectAsState is Composable-only" are at odds here, which makes me think there's "the way" to do this sort of thing that I'm not seeing right now.Ryan Smith
10/27/2022, 2:04 AMGenerally-speaking,is done to connect the reactivecollectAsState()
into the UI/Compose world. ViewModels, by nature, live above the UI, and so should not be usingFlow
, but instead still working withState<T>
.Flow
So what you’d want to do is have your ViewModel process your Repository’s Flow in some manner, and then expose its own Flow (or StateFlow) which contains the data from the Repository and also the other stuff you’re managing in your ViewModel. And then your Compose code callson your ViewModel’s Flow, and is completely ignorant of the RepositorycollectAsState()
Ben Trengrove [G]
10/27/2022, 2:17 AM// Stateful
@Composable
fun ItemScreen(viewModel = viewModel()) {
val items = viewModel.items.collectAsState()
ItemContent(items)
}
// Stateless
fun ItemContent(items: List<Item>) {
...
}
Ben Trengrove [G]
10/27/2022, 2:17 AMBen Trengrove [G]
10/27/2022, 2:17 AMItemContent
with fake datamattinger
10/27/2022, 2:28 AMRyan Smith
10/29/2022, 3:28 PM