frankelot
06/10/2021, 8:30 AMMutableState<T>
and MutableStateFlow<T>
, when should I use each?frankelot
06/10/2021, 8:32 AM.collectAsState()
seems like I can use either one and just use ^^ 🤔 but I’m sure each has their own intender purposesRafs
06/10/2021, 8:33 AMMutableState<T>
only exists in compose world but MutableStateFlow<T>
can be used in any Kotlin code. You will need to call collectAsState
on a MutableStateFlow
to use it in compose.gildor
06/10/2021, 8:33 AMfrankelot
06/10/2021, 8:35 AM.collectAsState()
frankelot
06/10/2021, 8:35 AMgildor
06/10/2021, 8:36 AMgildor
06/10/2021, 8:37 AMfrankelot
06/10/2021, 8:42 AMfrankelot
06/10/2021, 8:43 AMcollectAsState()
cause it’s easy to just call .value
.. code will compile but you won’t get updates when the underlying data changesgildor
06/10/2021, 8:53 AMgildor
06/10/2021, 8:53 AMfrankelot
06/10/2021, 8:59 AM.value
frankelot
06/10/2021, 8:59 AM@Composable
fun MyText(foo : MutableStateFlow<String>) {
Text(text = foo.collectAsState().value)
}
frankelot
06/10/2021, 9:00 AM@Composable
fun MyText(foo : MutableState<String>) {
Text(text = foo.value)
}
frankelot
06/10/2021, 9:00 AMgildor
06/10/2021, 9:00 AMAlbert Chang
06/10/2021, 9:00 AMMutableState
is a better choice. More info here.gildor
06/10/2021, 9:01 AMgildor
06/10/2021, 9:03 AMthings consumed by your UII think this is my biggest issue, I would like to keep my VM agnostic to UI and more flexible
frankelot
06/10/2021, 9:03 AMfrankelot
06/10/2021, 9:03 AMfrankelot
06/10/2021, 9:04 AMgildor
06/10/2021, 9:05 AMfrankelot
06/10/2021, 9:06 AMyou don’t want to expose mutability in your VMgood point
Albert Chang
06/10/2021, 9:06 AMderivedStateOf
?gildor
06/10/2021, 9:07 AMgildor
06/10/2021, 9:09 AMAlbert Chang
06/10/2021, 9:09 AMAlbert Chang
06/10/2021, 9:10 AMMutableState
I don't mean exposing it. This is absolutely possible (and preferable):
class MyViewModel {
var someVar by mutableStateOf(0)
private set
}
gildor
06/10/2021, 9:12 AMAlbert Chang
06/10/2021, 9:12 AMAlbert Chang
06/10/2021, 9:14 AMgildor
06/10/2021, 9:14 AMgildor
06/10/2021, 9:14 AMAlbert Chang
06/10/2021, 9:15 AMAlbert Chang
06/10/2021, 9:15 AMgildor
06/10/2021, 9:15 AMgildor
06/10/2021, 9:16 AMfrankelot
06/10/2021, 9:17 AMAlbert Chang
06/10/2021, 9:27 AMStateFlow
in terms of unit test? Can you show an example?frankelot
06/10/2021, 9:35 AMAlbert Chang
06/10/2021, 9:39 AMState
is not Android-specific.frankelot
06/10/2021, 9:43 AMfrankelot
06/10/2021, 9:46 AMfrankelot
06/10/2021, 9:46 AMrxjava
and livedata
… IMO It introduces more confusion than anything elseAlbert Chang
06/10/2021, 9:51 AMState
, it is needed for the snapshot system, which is a core component of compose. Read the post I linked above (and other posts in that series) for more details. The third post should have answered this specific question.frankelot
06/10/2021, 10:06 AMThey all come with a reason.IDK about compose, but for livedata the reason was “it’s easier for beginners to use RxJava”. Which is a pretty bad one IMO, since now beginners need to learn even more stuff (which more experienced developers don’t really mind)
frankelot
06/10/2021, 10:07 AMAlbert Chang
06/10/2021, 10:08 AMLiveData
exists because it has better interoperability with Android lifecycles.frankelot
06/10/2021, 10:09 AMColton Idle
06/10/2021, 1:28 PMAdam Powell
06/10/2021, 3:12 PM[Mutable]StateFlow
over snapshot [Mutable]State
but, "it's compose-only" isn't one of them any more than, "it's kotlinx.coroutines-only" should be a reason not to use Flows. Snapshots are lower-level than the compose compiler plugin or any other compose-runtime machinery and can be used without any of it.Adam Powell
06/10/2021, 3:13 PMcompose-runtime
artifact and compose-runtime
includes other things is like declining to use suspendCancellableCoroutine
because the same artifact includes Flow
.Adam Powell
06/10/2021, 3:13 PMAdam Powell
06/10/2021, 3:15 PMsnapshotFlow {}
API - you can get a cold flow from any block of code or expression that reads snapshot state and it will bridge the two, no @Composable
or compose compiler plugin required.Adam Powell
06/10/2021, 3:16 PM[Mutable]StateFlow
out there would be better served by snapshots.Adam Powell
06/10/2021, 3:17 PM.stateIn(SharingStarted.WhileSubscribed)
Adam Powell
06/10/2021, 3:18 PMRecomposer
exposes current state information using StateFlow
, not snapshot state. It's a better fit for a bunch of timing and isolation-related reasons.Adam Powell
06/10/2021, 3:24 PMAdam Powell
06/10/2021, 3:27 PMSnapshot.sendApplyNotifications()
), you can perform your own isolated transactions of several changes all at once that you can then examine and assert on atomically, regardless of any other concurrency setup that might be active (the other APIs on `Snapshot`'s companion object itself)Adam Powell
06/10/2021, 3:31 PMViewModel
class) and consuming its state from compose using Flow.collectAsState
, you're not using Flow instead of snapshot state, you're using Flow and snapshot state - collectAsState
collects the flow into a snapshot state object for compose to react to. When you do this you lose the atomic transaction properties of snapshots.Adam Powell
06/10/2021, 3:32 PMAdam Powell
06/10/2021, 3:33 PMfrankelot
06/11/2021, 5:11 PM