escodro
02/18/2021, 5:02 PMsealed classes
via StateFlow
).
How could I handle the state changes?
1. Combine both states (with .combine
) and create a third “ViewState” mixing and matching the two states.
2. Observe both individually and let my function recompose when they change
3. Another better approach?
The first ViewModel has three states: EmptyList, LoadedList, Error and the second one has two: DataLoaded and Error.
Thanks and advance! 🎉Adam Powell
02/18/2021, 5:07 PM[Mutable]State<T>
instead of StateFlow
you get snapshot consistency of both plus observability for freeescodro
02/18/2021, 5:14 PMStateFlow
to State
and observing both will be better than doing so with StateFlow
?Casey Brooks
02/18/2021, 5:16 PM.collectAsState()
).
If they are related, I like to choose one as the “parent” VM and collect that one in the “child” VM, and only collectAsState()
on the child VM (basically making a hierarchy of VMs, rather than a loose network of them which are collected in various places). The child VM emits a state object which includes the necessary properties from its parent (with any necessary transformations), as well as its own stateAdam Powell
02/18/2021, 5:26 PMby mutableStateOf
properties on the class, yeah. And withMutableSnapshot {}
whenever several things need to change as part of a single snapshot transactionescodro
02/18/2021, 5:38 PMval detailViewState by detailViewModel.state
val categoryViewState by categoryViewModel.state
withMutableSnapshot {
TaskDetailRouter(
detailViewState = detailViewState,
categoryViewState = categoryViewState
)
}
Adam Powell
02/18/2021, 6:08 PMwithMutableSnapshot
is used when you're actually performing mutations that should be seen as atomicwithMutableSnapshot
)escodro
02/18/2021, 6:13 PMAdam Powell
02/18/2021, 6:17 PMStateFlow
and go directly to by mutableStateOf
object properties because the StateFlow
isn't buying you anything here unless it's coming from a .stateIn
from other cold flows. If you're using MutableStateFlow
you're adding unnecessary complexity and steps, since .collectAsState()
creates a mutableStateOf
and writes into it using a `LaunchedEffect`/`.collect` anyway.escodro
02/18/2021, 6:19 PMStateFlow
as well.
Thanks a lot! 😊Adam Powell
02/18/2021, 6:22 PMclass MyState(private val dep: Dependency) {
var foo by mutableStateOf(...)
private set
val bar: Bar
get() = dep.bar
fun updateFoo(...) {
foo = ...
}
}
then using it this way:
val myState = remember(dep) { MyState(dep) }
Button(onClick = { myState.updateFoo(...) } {
Text("Click to update")
}
Image(imageFor(myState.bar)), myState.bar.description)
then anything that is backed by mutableStateOf
under the hood is observable, and when any of it changes the right thing will recompose. You can use this to maintain single sources of truth, and other objects' functions and properties can simply reference those sources of truth naturally.escodro
02/18/2021, 6:27 PMAdam Powell
02/18/2021, 6:33 PMsnapshotFlow {}
API exist; it's an easy way to observe snapshot-powered objects written in the style I described above and consume it from other parts of your app that already speak Flowescodro
02/18/2021, 6:40 PMAdam Powell
02/18/2021, 6:45 PM