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!