mutableStateOf(list) vs mutableStateListOf()
The best way to work with lists and state in Jetpack Compose.
When working with lists in Jetpack Compose, you’ll end up seeing both mutableStateOf(listOf<T>())
and mutableStateListOf<T>()
. They look pretty similar, but they have different purposes. Here’s a rundown on which one to use in what situation, as well what to do with other mutableState*Of
functions.
Use mutableStateOf
when working with immutable lists
State
is designed to work with a single value. It only triggers recomposition if the value changes (if oldValue == newValue
is false). If you pass in a list, it will only trigger recomposition if the list reference changes. If you’re working with a mutable list, the reference isn’t going to change so you won’t end up seeing your mutations reflected in the UI. Any changes to your list will need to be done by making a new copy.
However, if you’re never changing the list yourself, this can be a good benefit. For example, if you’re working with a Room database, you don’t want to change a list of items returned from the database through mutation because the database itself won’t be changed. This is the same reason you would use List
instead of MutableList
- it makes it clear that the list should be treated as immutable.
Use mutableStateListOf
when working with mutable lists
On the other hand, if you do want to mutate the list, you’ll want to have any mutations trigger recomposition. This is where mutableStateListOf
comes in. It’s a MutableList
that triggers recomposition when it’s mutated.
You can think of it as a replacement for MutableList
rather than a replacement for State
or List
. Reach for mutableStateListOf
when you want to work with a mutable list (not a regular list) and have your changes reflected in the UI.
mutableStateMapOf
follows the same pattern, but for maps
mutableStateMapOf
is the same as mutableStateListOf
, but for maps. It’s a MutableMap
that triggers recomposition when it’s mutated.
If you need to be able to mutate your map inside of a composable, you’ll want to use mutableStateMapOf
. Otherwise you’ll want to use a regular Map
and mutableStateOf
.
mutableDoubleStateOf
, mutableFloatStateOf
, mutableIntStateOf
, and mutableLongStateOf
are for primitive types
mutableDoubleStateOf
, mutableFloatStateOf
, mutableIntStateOf
, and mutableLongStateOf
are all equivalent to mutableStateOf
, except they avoid autoboxing in JVM platforms (like Android). As a result, they’re more memory efficient and should be preferred when working with primitive types.