Reputation: 7281
In Jetpack Compose, it's common to pass lambda functions as parameters in both stateful and stateless composables. I'm considering using interfaces for this purpose instead and would like to understand the implications of this approach.
Is using interfaces instead of lambda functions in this context against Jetpack Compose guidelines or best practices?
What are the potential drawbacks of using interfaces in place of lambda functions for passing callbacks or other functional parameters in Composables?
Simple example:interface
MyComposableCallback {
fun onEventOccurred(data: String)
}
@Composable
fun MyComposable(callback: MyComposableCallback) {
// Composable implementation
}
// Usage
val myCallback = object : MyComposableCallback {
override fun onEventOccurred(data: String) {
// Handle event
}
}
MyComposable(callback = myCallback)
As opposed to the more conventional lambda approach:
@Composable
fun MyComposable(onEventOccurred: (String) -> Unit) {
// Composable implementation
}
// Usage
MyComposable { data ->
// Handle event
}
Any insights on the pros and cons of each approach in terms of performance, readability, and adherence to Compose principles would be greatly appreciated.
Upvotes: 2
Views: 747
Reputation: 376
an interface could affect to recompositions because it's unstable
documentation said:
Compose considers a type stable only if it can prove it. For example, an interface is generally treated as not stable, and types with mutable public properties whose implementation could be immutable are not stable either.
If Compose is not able to infer that a type is stable, but you want to force Compose to treat it as stable, mark it with the @Stable annotation
Example
// Marking the type as stable to favor skipping and smart recompositions.
@Stable
interface UiState<T : Result<T>> {
val value: T?
val exception: Throwable?
val hasError: Boolean
get() = exception != null
}
Link -> https://developer.android.com/jetpack/compose/lifecycle
I recommend you better to use an Actions class in your composable.
Ejem
data class MyComposableCallbackActions(
val onEventOccurred: (String) -> Unit
)
@Composable
fun rememberMyComposableCallbackActions(
viewmodel: ViewModel
): MyComposableCallbackActions =
remember {
MyComposableCallbackActions(
onEventOccurred = viewmodel::onEventOccurred
)
}
@Composable
fun MyComposable(actions: MyComposableCallbackActions) {
// Composable implementation
}
This allows us to introduce the same level and ease of grouping our Actions related to our Screen and a more simple way to pass these actions to the relevant components.
"remember" help you to avoid unnecessary UI re-rendering.
Link -> https://levinzon-roman.medium.com/jetpack-compose-ui-architecture-a34c4d3e4391
Upvotes: 2