compose-multiplatform
compose-multiplatform copied to clipboard
Recomposition happens when Compose code comes from a dependency module
Please check out this project which demonstrates the issue:
https://github.com/DennisTsar/bug-reports/tree/kotlin/compose/recomposition-1
Copying the README from that project here:
Compose 1.6.0+ Recomposition Issue
- Run
./gradlew app:jvmRun -DmainClass=MainKtor./gradlew app:jsBrowserDevelopmentRunand enter text into the textfield. Observe that the firstCustomRowdoes not recompose on button click, but the second does. - If contents of
libare moved toapp, the issue goes away - JVM behavior has occurred since at least Compose 1.5.12/Kotlin 1.9.22
- JS behavior began with Compose 1.6.0/Kotlin 1.9.22
- Still present on both targets with Compose 1.6.11 & Kotlin 2.0.0
Just to emphasize how problematic this bug potentially is, I added the following code to my local project (a web project built using Kobweb):
var msg by remember { mutableStateOf("") }
TextInput(msg, onTextChanged = { msg = it }, ...)
// Sibling element which should NOT be affected by text input changes
Row(horizontalArrangement = Arrangement.spacedBy(10.px)) {
var recomposeCount by remember { mutableStateOf(0) }
recomposeCount++
Text("Recompose count: $recomposeCount (should stay at 1)")
}
I expected one extra recomposition per character I typed into my text box, which would already have been a little bad, but instead I got a case of infinite, non-ending recompositions! This would have been invisible waste if I hadn't surfaced them via a text element:
https://github.com/JetBrains/compose-multiplatform/assets/43705986/f783ef92-bb29-458d-9656-5e5c60da947a
Once I added the @Immutable annotation to the empty RowScope interface (as the repro project suggests as a possible fix), the recompositions stopped.
This is clearly not intended behavior; Compose should not be getting confused about the immutability of an empty interface.
Does it behave differently on Android?
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.