Is there much difference between `SnapshotStateLis...
# compose
d
Is there much difference between
SnapshotStateList<T>
and
MutableState<List<T>>
? In particular, is there any difference in the granularity of how mutations trigger recomposition? (Like in a
LazyColumnFor
)
a
The former is basically a fancy version of the latter, but that uses the kotlinx immutable collections and some other optimizations under the hood for efficiency
d
Thanks for answering! Should I always be using the former if I can?
a
If you need snapshot observability, and you're making enough changes that you don't want to be creating copies of a non-persistent data structure frequently, then it's a good choice
l
I dunno if I would agree with
SnapshotStateList<T>
as a fancy version of
MutableState<List<T>>
. When you’re using the latter, you’re essentially treating the list itself as an immutable piece of data, and whenver you want to change it, you have to provide a whole new list. So for example, to add an item in the middle of the list:
Copy code
state.value =  
  state.value.let { 
    it.subList(0, n) + item + it.subList(n)
  }
This is because the “tracking” is really done on a single value, not on the individual elements of the list. You have a “tracked” reference to a list, and you’re updating what that reference points to. On the other hand, the SnapshotStateList is made to look like a MutableList, but all mutations are tracked properly by Compose. For instance, adding an element in the middle of the list is just:
Copy code
state.insertAt(n, item)
This is really handy if you’re really thinking of the list and its elements as the stateful part of your app. However, I tend to lean away from SnapshotStateList in most cases just because I think the MutableState<List> variant is not going to be any worse performance wise and it introduces fewer new concepts into your app (ie, you are probably already familiar using both MutableState and List all over the place, but likely not SnapshotStateList). That said, it can be very useful in specific situations.
👍 4
a
Matter of taste I suppose 🙂 also depends on whether or not you're passing the reference around to places that might need a persistent copy
d
I think the
Snapshot
in the name is somewhat misleading. I think the name
MutableStateList
would have more/less helped me quickly appreciate the difference.
Thanks for taking the time to explain!
a
mutableStateListOf
:
SnapshotStateList
::
mutableListOf
:
ArrayList
- the factory method speaks to the interface you'll get back but the concrete type describes itself rather than the interface it implements
143 Views