Anyone had to debounce onClick lambdas yet in Compose? Or immediately disable a button to prevent mu...
a
Anyone had to debounce onClick lambdas yet in Compose? Or immediately disable a button to prevent multiple clicks. We hoisted the state into the ViewModel and there’s a gap where the user can still click the button again before it gets disabled. Been trying to think of ways to handle this.
Checked how people do it in React and it seems they mutate the state directly within the component, which makes that component stateful in terms of the button enable state. I wonder if that is a good approach in Compose.
k
It seems like you want to disable a button when it’s pressed, to avoid multiple clicks. I think, in that case, I’d have internal button state, which is dependent on the outside’s state. So that once the user clicks, you changed internal state to
not-clickable
, awaiting the response from click handler (to toggle it back on or off)
a
I imagine something like this
Copy code
var loginButtonEnabled by remember(state.loginButtonEnabled) {
    mutableStateOf(state.loginButtonEnabled)
}
Button(
    onClick = { loginButtonEnabled = false },
    enabled = loginButtonEnabled
) {
    Text("Login")
}
What do you think?
This is just for the case of preventing multiple clicks for buttons though. For something that’s really needs a debounce like realtime search I wonder if I should convert lambdas into Flow in order to debounce it…
k
Worth trying
a
thanks @krzysztof
k
Let me know the results, once you test it
a
I'd prefer to have a single source of truth in the domain modeling instead of trying to create a generalized debouncing button. Something more like:
Copy code
Button(
  onClick = { loginState.beginLogin() },
  enabled = !loginState.isLoginInProgress
) { // ...
🙌 3
🙌🏽 1
loginState
then is what's responsible for making sure you don't begin the login process multiple times, etc.
rather than the UI itself. The UI just reflects the application state
a
Yeah, that’s what I’ve been doing and with ViewModels and StateFlow. Problem is there’s a delay in between the state update and the next recompose, and the user can click again during that time. Is there something I could use to mitigate that problem? Consider the following snippet
a
Have beginLogin check to see if the state is already logging in before beginning a new login
That policy enforcement should be part of your business logic, not the UI that invokes the business logic
☝🏼 1
a
Ohh, yeah. That’s a simpler and effective solution. I’ll try it! Thanks
a
also way easier to unit test - you only need to test your ViewModel for this behavior, not the UI that calls into it
176 Views