https://kotlinlang.org logo
#compose
Title
# compose
b

Billy Newman

08/10/2021, 7:02 PM
Hello all, I am having some issues with a recompose not running when replacing an immutable list
c

Colton Idle

08/10/2021, 7:04 PM
@Billy Newman can you edit your post to put the code in this thread please? https://kotlinlang.slack.com/archives/CJLTWPH7S/p1616265877303000
b

Billy Newman

08/10/2021, 7:17 PM
I have a list of objects that is immutable. There is a property that I am using in each object to determine whether or not I want to show the object. The parent composable does the filtering:
Copy code
@Composable
fun Stuff(state: StuffState) {
  val values = state.values?.filter { it.visible == true }
  ...
  ValuesContent(values)
}
Copy code
@Composable
fun ValuesContent(values: List<Stuff>) {
   values.forEach { stuff ->
      // show stuff here...
   }
}
I modify the state in the viewModel by replacing the entire list with a new list.
Copy code
val newValues = values.toMutableList() // this should create a new list
newValues.find { /* update some object */ }?.let {
   it.visible = false
}

state.values = newValues
I am pretty sure if a new list is created a recompose should trigger. Is this still true? Something else I am doing wrong?
@Ravi I get this “Assuming you’re using the data correctly, Compose should just work, and you shouldn’t have to think any more about it”, however that is where I am stuck. I am using an immutable list. and when I replace that list, a recompose is not happening
r

Ravi

08/10/2021, 8:10 PM
you should consume your
StuffState
as State [
collectAsState
or
observeAsState
]
you can use
snapshotFlow { state.values }.collect { … }
b

Billy Newman

08/10/2021, 8:34 PM
its just a list, not coming from flow or livedata. still does not fully make sense, everything I have read points to using immutable objects. I am using an immutable list, when anything in that list changes I create a new list, far as I can tell a new immutable object, in this case a list should recompose such that UI updates accordingly to not show the filtered values.
Copy code
@Composable
fun HelloContent(name: String) { ... }
The name string is immutable here, if it changes a recompose will happen to update any views in the HelloContent composable.
Copy code
@Composable
fun HelloContent(names: List<String>) { ... }
The name list here is immutable as well, if it changes shouldn’t a recompose fire to update the view?
@Ravi you were of course right, was just having a hard time finding out why, as most on internet are incorrect. Here from official docs: https://developer.android.com/jetpack/compose/state:
Copy code
Caution: Using mutable objects such as ArrayList<T> or mutableListOf() as state in Compose will cause your users to see incorrect or stale data in your app.

Mutable objects that are not observable, such as ArrayList<T> or a mutable data class, cannot be observed by Compose to trigger recomposition when they change.

Instead of using non-observable mutable objects, we recommend you use an observable data holder such as State<List<T>> and the immutable listOf().
👍 1
b

Billy Newman

08/10/2021, 8:51 PM
Will do, thanks for pointing me down the right path!
18 Views