Csaba Kozák
09/14/2021, 3:05 PMkotlin.collections.List
interface to represent a list of data. However the List
interface is not @Stable
. My experience shows that if a composable function is called with the same List
of strings, it will always recompose. Should we use another type to represent `List`s (and other collections) in compose? This could be also a broader question, since lots of built-in immutable types (like LocalDateTime
) are not considered stable by the compose compiler. I added example code in 🧵Csaba Kozák
09/14/2021, 3:05 PM@Composable
fun RecompositionTest() {
var counter by remember { mutableStateOf(0) }
val list = listOf("compose") // does not change
LaunchedEffect(Unit) {
while (true) {
delay(1000L)
counter++
}
}
Content(list, counter)
}
@Composable
private fun Content(list: List<String>, counter: Int) {
Text(text = "count $counter")
MyList(list = list) // this will always recompose because List is not @Stable
MyList(listWrapper = ListWrapper(list)) // only called once, ListWrapper is @Stable
}
@Composable
private fun MyList(list: List<String>) {
Column {
list.forEach {
Text(text = it)
}
}
}
@Composable
private fun MyList(listWrapper: ListWrapper) {
Column {
listWrapper.list.forEach {
Text(text = it)
}
}
}
@Stable
data class ListWrapper(val list: List<String>)
Csaba Kozák
09/15/2021, 9:45 AMCsaba Kozák
09/15/2021, 9:47 AMZach Klippenstein (he/him) [MOD]
09/16/2021, 12:22 PMList
doesn’t guarantee immutability so stability can’t be inferred. One way to do this that doesn’t involve a wrapper, and is probably more performant, might be to use a SnapshoteStateList
(i.e. mutableStateListOf
). But if you really want to force a whole-list comparison every time and are confidant that the list will not be mutated then i guess the wrapper approach should work.Csaba Kozák
09/16/2021, 12:28 PMmutableStateListOf()
? Just wrap every list what we have, and pass that down to composables?Zach Klippenstein (he/him) [MOD]
09/16/2021, 5:15 PMCsaba Kozák
09/17/2021, 7:56 AMZach Klippenstein (he/him) [MOD]
09/17/2021, 4:12 PMCsaba Kozák
09/17/2021, 4:14 PMkotlinx.immutable
by default. I guess that would be the ideal solution. Until then, we could use a wrapper.Zach Klippenstein (he/him) [MOD]
09/17/2021, 4:29 PMmutableStateListOf
is actually just basically a wrapper around an immutable list inside a mutable state.