I don't know why in my code the text where I type "hi" is always recomposed. The text was fixed to "hi", and onClick also maintained the instance using uiEvent remember.
Even if uiState.isLoading is changed, it is not related to Text, so I expected that recomposition would be skipped, but recomposition always occurs when Text is changed.
Here is my code:
data class UiState(
val isLoading: Boolean
)
@Immutable
interface UiEvent {
fun onClick()
}
@Composable
fun MyScreen(
viewModel: MyViewModel = hiltViewModels()
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
val uiEvent = remember {
object: UiEvent {
override onClick() {
viewModel.action()
}
}
}
Text( // why recomposition?
modifier = Modifier.clickable(onClick = uiEvent::onClick),
text = "hi"
)
if (uiState.isLoading) {
Text(text = "isLoading")
}
}
I assume what you are asking is why does Text not skip whenever MyScreen recomposes. The reason is a new of the clickable modifier is being created every time. Consider remembering the entire modifier such as:
@Composable
fun MyScreen(
viewModel: MyViewModel = hiltViewModels()
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
val modifier = remember(viewModel) {
val event = object: UiEvent {
override fun onClick() {
viewModel.action()
}
}
Modifier.clickable { event.onClick() }
}
Text( // why recomposition?
modifier = modifier,
text = "hi"
)
if (uiState.isLoading) {
Text(text = "isLoading")
}
}
Note the addition of the viewModel as a parameter to the remember to ensure a new version of clickable() gets created if/when the viewModel changes.
The compose compiler plugin should recognize the :: syntax and do the remember for you, like it does for lambda syntax, but it doesn't right now. Also, the clickable() always returns a modifier that is not equal to the previous version for the same parameters, but that is going to be fixed in 1.5 (along with quite a number of other performance related fixes for clickable()). For now, you can work around these limitation by remembering the entire modifier.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With