Is it OK to group callbacks like this to be passed into a composable?
Copy code
data class HomeCallbacks(
val onCallback1: () -> Unit,
val onCallback2: () -> Unit,
val onCallback3: () -> Unit,
)
fun HomeScreen(
state: HomeState,
callbacks: HomeCallbacks = HomeCallbacks()
) {
// ...
}
👍 2
👍🏽 1
p
Pablichjenkov
07/25/2025, 12:33 AM
I have used this pattern and it is really handy, it saves typing time and your Composables signature don't bloat with so many callbacks. I actually created a mini API around it where I add interceptors to the events. Sometimes you want to intercept some specific event in a specific layer on the Composable side before it reaches the ViewModel, or the state where the callback is instantiated.
👍 1
j
Jonathan
07/25/2025, 3:53 AM
A nice solution would be to have one callback and use
sealed classes
to represent different events you want to observe. I think it makes the calling code cleaner and makes adding new "events" dirt simple. Using a sealed class in a when statement has to be exhaustive so you don't have to worry about forgetting to implement an event.
👍🏽 1
👍 1
p
Pablichjenkov
07/25/2025, 4:25 AM
That works great too. I actually moved to this last pattern recently. You can associate the events that are related. Likewise you can have multiple callbacks too.
k
KamilH
07/25/2025, 7:11 AM
For
sealed Event
solutions, I’ve always wondered about the memory impact, especially for quickly occurring events like
OnTextChanged
, etc. I’ve never measured it, though, and I think this could be mitigated by using a
value class
The downside is also that we are tightly coupling UI components with events unless we use lambdas everywhere and the “event sink” on the “screen” level
đź’ˇ 1
j
Jonathan
07/25/2025, 12:04 PM
For text changing events, you should opt for using TextFieldState instead of a callback. Ideally most of your callbacks could be
data object
so you’d have as little allocations as possible.