Suppose I have a composable accepting an immutable...
# compose
m
Suppose I have a composable accepting an immutable UI state represented by a sealed interface. This composable delegates to the relevant composable according to the UI state concrete subclass. However, I want to declare event handlers relevant to only one of those types (needs to be handled by the view model). Should those be passed as arguments alongside the general UI state, or is there another way, for example on the concrete subclass itself? I’m guessing the latter is an anti pattern.
z
Make the event handlers function properties in the concrete state classes
Copy code
data class MyState(
  val something: String,
  val onSomethingClicked: () -> Unit
)
d
I would advise against this approach. I would advise instead, out of principle, passing the lambda into the Composable component as an argument instead. The reason being is for flexibility. Often the UI layer wants to do things that may fall outside of the ViewModel’s set of responsibilities. By passing the lambda in from the UI layer your code will allow for easier growth and maintainability over time.
m
The problem with passing as a composable argument is what about event handlers specific to only very obscure subclasses? There may well be cases where you call a composable with UI state where that obscure subclass is never present, in which case it makes no sense to pass the event handler
@Zach Klippenstein (he/him) [MOD] yes this is what I had in mind, but I was just wondering if it’s an anti-pattern as I haven’t seen this done like that before.
z
I wouldn’t consider it an anti pattern. I’ve seen numerous recent architecture libraries and patterns built around it. We did it with square workflow, which has been used extensively at square for a few years now.
It allows the only coupling between your view model and your view to be a single state class, which is nice and clean.
thank you color 1
m
Thanks, and I presume such a data class would still be considered
@Immutable
because those handlers are not called as part of composition/recomposition etc?
z
They’d be properly immutable in every sense of the word because the function represents code, and that code is immutable. Where you call the functions doesn’t affect their mutability.
m
I think the other concern would be that the class now has two responsibilities - ui state and event handling - and so is a code smell.
1