Hello there, Is it Safe to Include Lambdas in Jetp...
# compose
c
Hello there, Is it Safe to Include Lambdas in Jetpack Compose UI State? (more details in 🧵⤵️)
I'm working with Jetpack Compose for my app and have come across a scenario where I find it convenient to store lambdas as part of my UI state. Specifically, I have a data class that represents the state of a UI component, and in addition to traditional state data like Strings or Integers, I have lambdas for handling certain events.
Copy code
data class MyTextFieldUiState(
    val value: String = "",
    val onFocusIsLost: () -> Unit = {},
    val onValueChange: (String) -> Unit = {}
)
I utilize this state in a Composable as follows:
Copy code
@Composable
fun MyTextField(uiState: MyTextFieldUiState) {
    TextField(
        value = uiState.value,
        onValueChange = { newValue ->
            uiState.onValueChange(newValue)
        },
        modifier = Modifier.onFocusChanged { focusState ->
            if (focusState == FocusState.Inactive) {
                uiState.onFocusIsLost()
            }
        }
    )
}
My concerns are: 1. Does having lambdas as part of the state lead to any unexpected recompositions? 2. Is there a potential performance hit? 3. Is this pattern considered a best practice, or is there a more recommended way to handle event callbacks in Compose? Any insights would be much appreciated!
x
AFAIK, that lambda should be stable and you should have no performance penalty. However, the best way to check this out is by using the Compose compiler metrics
👍 1
c
I'd recommend to take a look at this. Getting events from the UI to the ViewModel (or vice versa) would be done with new objects (sealed classes) for UIEvents or regular Events. For a YouTube reference you can always take a look at the

Philip Lackner's

stuff. He uses this pattern a lot. https://developer.android.com/topic/architecture/ui-layer/events
👍 1
b
I don’t recommend this practice. One big reason would be that testing is a pain here. How do you test your emitted model? How do you confirm the lambda has the right behavior? And that’s gonna be even more painful to test the more it needs parameters. I’d emit
Copy code
data class MyTextFieldUiState(
    val value: String = "",
)
and the view would simply expose two events
data object OnFocusIsLost
and
data class OnValueChange(string)
which the presenter would react to.
1
I think some people on our team did that and the past and they understood the pain. We dont’ have any anymore in our codebase.
And yo how would you test the lambda? You have to emit a model first, consume that model, and execute the lambda !?
That’s what tests should look like
🙏 1
c
And yo how would you test the lambda? You have to emit a model first, consume that model, and execute the lambda !?
I will obtain an initial state, execute the lambda, and verify if the ViewModel/Presenter sends a new state with a new value. You are right; ensuring that the ViewModel/Presenter is in the correct state before executing the lambda can be a challenging task.
s
Benoit, is this last slide from some talk/presentation? It looks like it from the text being cut/off from the top-right. If yes I’m curious to see the rest of it too 😊
b
It’s just a link to the molecule library https://github.com/cashapp/molecule
s
Oh alright, but did this screenshot come from some presentation? That's what I was wondering 👀
b
https://speakerdeck.com/oldergod/sweet-architecture

https://www.youtube.com/watch?v=mbYzcF43fbc

s
Thanks a lot!