One Off the Slack: Immutability Is Your Friend
As with last week’s highlighted Slack thread, this one focuses on state change detection and mutability.
Colton Idle asked:
My activity has a field myTodoList mutableListOf
and it has items added to it by another source (right now I have a post delayed handler that waits for 5 seconds, and then adds ten items) and I expect the items to update this Screen composable, but nothing shows.
Mutable stuff (var
, MutableList
, etc.) is fine, but Compose knows nothing about
it. On the whole, Compose — particualarly State
— works much better
with immutable objects.
As Florian Schuster put it:
Your problem lies not in compose but with your list in your activity. The list needs to be observable if you want your composables to recompose on a change of the items in the list. Either use a Flow
, LiveData
or mutableStateOf(List), hand that over to your MyActivityScreen and observe it in there.
Colton then tried:
val listOfItems = mutableStateOf(mutableListOf<String>())
and:
listOfItems.value.add("adsf")
However, this still uses MutableList
. State
and MutableState
know when
you supply a fresh value, but they do not know when you change the internals
of the existing value, such as adding an element to the MutableList
.
Florian suggested:
val listOfItems = mutableStateOf(listOf<String>())
and:
listOfItems.value = listOf("a", "b" )
And in the end that wound up being the solution.
In general, in Kotlin, prefer immutable things to mutable ones (val
instead of var
,
List
instead of MutableList
). Unidirectional data flow architectures tend to rely
on this convention, and Compose leans into it as well.
Read the original thread in the kotlinlang Slack workspace. Not a member? Join that Slack workspace here!