What’s the right way to include the value of a Sta...
# compose
c
What’s the right way to include the value of a StateFlow in
derivedStateOf
? (In a VM)
I have a VM like
Copy code
class MyViewModel : ViewModel() {
  val myStateFlow = MutableStateFlow(...)
  val myDerivedState = derivedStateOf {
    // I would like to use the value of myStateFlow here
  }
}
In a
@Composable
I could collectAsState… but I’m not sure what to do outside that context
Thanks for any help
m
val state by remember(viewModel){…collectAsState() }
derivedStateOf { state.sth }
c
That’s in a composable context, whereas I am trying to use derivedStateOf in a VM.
n
If your VM has a coroutine scope, just collect the flow and pass the value to some mutableStateOf().
c
Oh yeah that makes sense. Maybe I’ll write an extension to do that
Thanks for responding everyone
m
derivedStateOf only works on another state variables. Why not use myStateFlow.map{ … }. You dont need derivedState in viewModel
c
My actual VM uses derivedStateOf with a few `State`s and I wanted to also use a
StateFlow
. Is there a reason you suggest I shouldn’t use derivedStateOf in a VM?
m
yes. derivedStateOf is compose related. You can, but should not use it in viewModel. Besides, you can use flows for anything related to compose state, so why would you use mutableState/derivedState in viewmodel anyway
c
State
is part of compose
runtime
, so I don’t see it makes a difference whether I have a dependency on the compose runtime vs coroutines/flow. I would argue you should use whatever satisfies your use case. But I’d be open to hearing arguments otherwise.
n
It’s totally fine. I’d just try to stay consistent with your choice across your VMs.
👎 1
m
The more abstractions the more complex your code becomes. You already use flows in viewModel, you dont need derivedStateOf or mutableStateOf in the mix
👍 2
z
Use whatever makes sense for your architecture. There are pros/cons to StateFlow/snapshot state other than which library artifacts they come from, evaluate based on those first. Snapshot state is a really powerful thing that might end up simplifying a lot of code if you use it pervasively enough.
c
Yeah I do like the simplicity of compose State. I’ve been trying to use it more lately in lieu of StateFlow, but I find I’ll reach for StateFlow if I need effects via onEach in non-compose context
t
We do use Snapshot state in our VMs in some cases (VMs differ drastically, and we try to approach on a case-by-case basis) In this case, we might drop the `StateFlow`:
Copy code
class MyViewModel : ViewModel() {
  val myState = mutableStateOf(...)
  val myDerivedState = derivedStateOf {
    // Some function of myState...
  }
  ...
  // Set myState.value in the same place you updated StateFlow
}
This is the only way I can think of if you really want to expose Snapshot state, because otherwise, there is no way to cross the
StateFlow
/Snapshot state boundary from a non-Compose context such as VM
z
if I need effects via onEach in non-compose context
Triggering effects on state change is always risky, since states can be conflated with both approaches. But just as you can go from a
StateFlow
to a
State
via
collectAsState
, you can always go from a
State
to a
Flow
with
snapshotFlow
.
👍 1
c
The effects I have in mind are of the “save changes” sort where conflation is desired. But I know what you mean otherwise 👍