HelloCW
HelloCW

Reputation: 2325

Can I use val expandedRecordIndex = mutableStateListOf<Int>() as observable mutable objects?

The following content comes from official article.

Caution: Using mutable objects such as ArrayList or mutableListOf() as state in Compose causes your users to see incorrect or stale data in your app. Mutable objects that are not observable, such as ArrayList or a mutable data class, are not observable by Compose and don't trigger a recomposition when they change. Instead of using non-observable mutable objects, the recommendation is to use an observable data holder such as State<List> and the immutable listOf().

1: It makes me confused, how can I use State<List<T>> and the immutable listOf() to create a observable mutable objects?

2: I think Code A is simple and it's a observable mutable objects, and I can change data using such as expandedRecordIndex.add(1) and UI will change too , right?

Code A

val expandedRecordIndex = mutableStateListOf<Int>()

Upvotes: 0

Views: 38

Answers (1)

Tenfour04
Tenfour04

Reputation: 93834

Yes, that code is fine. They wouldn't have included it in the library if it had no purpose. The difference between

Code A

val expandedRecordIndex = mutableStateListOf<Int>()

and

Code B

val expandedRecordIndex = mutableStateOf<List<Int>>(emptyList())

is that in Code A, you can directly modify the list, such as adding or removing an item, and it will automatically trigger recomposition. With Code B, you must create a new list instance and reassign it to the expandedRecordIndex.value to trigger recomposition. Code A may perform better for certain types of Composables because it makes it easier for Compose to determine exactly what has changed and what can be kept since the previous recomposition. Code B might be more convenient to use in some cases.

The documentation you're quoting is warning against you doing this:

Code C (BAD!!)

val expandedRecordIndex = mutableStateOf<MutableList<Int>>(mutableListOf())

With Code C, if you modify the mutable list in it, it will not trigger recomposition. And if you modify the list and then set it as the state again to try to make it recompose, like this:

expandedRecordIndex.value.add(3)
expandedRecordIndex.value = expandedRecordIndex.value

...it still won't work because new state and the old state are the same list instance. There is no old state that can be compared, so it cannot detect the change.

Upvotes: 1

Related Questions