hello, i have a screen with events i am refactorin...
# compose
a
hello, i have a screen with events i am refactoring from livedata to compose. previously i would handle events by having them on one livedata and doing
Copy code
viewmodel.events.observe { when (event) etc etc }
now my instinct is to have the events be a val on the uiState like
Copy code
UiState(val event)
and then in the composition
Copy code
SomeScreen(uiState) {
   LaunchedEffect(uiState.event) {
      when (event) etc etc
   }
}
but this causes a problem where in livedata you could post the same event in a row multiple times and the observer would trigger each time. i have to assume that if you copy the uiState and set the same event now the LaunchedEffect wont trigger. I can clear the event manually in the state each time, but the slight overhead makes me wonder if there's a better way to do it?
f
State != Event You should not represent events as a state. Consider using
SharedFlow
for this.
You can collect this flow in your UI
Copy code
LaunchedEffect(eventFlow) {
    eventFlow.collect { event ->
        when(event) { ... }
    }
}
a
awesome, thank you for the quick reply
a
You might want to take a look at this post alternatively: https://twitter.com/manuelvicnt/status/1532324889255940098?lang=en-GB 🙂
f
Right, I forgot about these new Android patterns. While I don't really agree with it, the article is worth reading at least. My (bad) experience with reducing events to state might be different than yours...
f
actually for Compose the recommendation is to treat events as state. Have a list of events, do a
LaunchedEffect
on the list, handle one, tell the viewmodel you handled it, the viewmodel will remove it from the list and your
LaunchedEffect
will trigger again so you can handle the next