-
Notifications
You must be signed in to change notification settings - Fork 44
FAQ
- if you have questions on how something would work the USF way, raise an issue
- i'll try to add more questions
I've broken this FAQ into two sections:
- How to do X
- Why do we Y
- Misc
The hardest problems for an android developer eventually always boil down to the lifecycle.
This question very similar to the next one but the question boils down to - "if i subscribe to a USF pipeline that internally sends a hot flow, will i leak memory?"
You don't. You might be tempted to use multiple VMs for the same screen, this is not a good idea as there can be view-state update collisions from different VM.
If you add a feature, or make a changes to an existing screen using the USF pattern, you're typically only working with one "strand" in the USF pipeline thread. So even if your class is big, the scope of changes you make is isolated. So personally, I don't have any qualms with the ViewModel going big, since most people would be dealing (typically) with different strands of the USFM thread.
That being said, you should leverage the UseCase
pattern to reuse functionality that might otherwise make your eventToResult
functions long.
Google came out with this article stating explicitly that one-off event(s) are anti-patterns. I disagree.
- The alternative to achieving this one-time side effect behavior is tracking the "state" of these effects in the UI state directly via
Boolean
values. That feels like a very ham-fisted way of dealing with the UI. - This recommendation predates many of the SideEffect apis that Compose has since introduced.
But let's dive in deeper: The tldr of that Google post is - when the producer outlives the consumer, these APIs don’t guarantee the delivery and processing of the events. Therefore, handle the event immediately in the VM and reduce it to state which is exposed using an observable data holder type (implying use a similar mechanism to how you manage the view state).
But that feels like a band-aid to the original problem which is guarantying the delivery and processing of events. We have constructs like Channel
s that have interesting properties allowing you to guarantee delivery for a subscriber, and queue/buffer up events before a subscriber shows up.
This reddit thread (strong language aside) captures a lot of how I think around this specific subject.
I also have a suite of unit tests covering many of these corner-case scenarios.
The other advantage we get by splitting is that a Result
object doesn't need to forcefully emit a UiState
or Effect
. We might selectively need to emit one or both.
It feels like an unnecessary intermediate abstraction. Why not try to transform directly into UiState
& Effect
s ?
- similar to the previous point having a
Result
object allows us to multicast theEvent → Result
stream (bulk of the work) and then selectively emit just aUiState
orEffect
(or both). You cannot achieve this without that abstraction -
Event → Result
also allows general reuse throughUseCase
s
Anecdotally, I did try with my iOS team initially who felt it added complexity. Eventually we reverted back to having a Result
object.
It's up to you. My personal preference is not to have this but rather capture that more directly in the ViewState class.
requires separate page.
- point to examples
- Sample Android app
- Sample iOS app