https://kotlinlang.org logo
Title
f

faisalahmed

03/10/2023, 11:20 AM
Hi folks, a question about
mutableStateListOf()
. add and remove on the list triggers succesful recompositions of the specific item, but changing the value at any index of this list does not trigger any recomposition. Been scratching my head at this. My
LazyColumn
is keyed to a unique
id
coming in the data as well. So I am wondering what might be going wrong. Following is an example. Inside
ViewModel
val list = mutableStateListOf<Messages>()

fun onMessageChanged(newMessage: Message) {
  val index = list.indexOf(newMessage) // returns correct index
  list[index] = newMessage // does not trigger recomposition
}
e

ephemient

03/10/2023, 11:23 AM
like
mutableStateOf()
, it compares with
==
. assigning the same state doesn't recompose
f

faisalahmed

03/10/2023, 11:25 AM
how can I trigger recomposition for a change in any item of the list?
v

Vojtěch Hořánek

03/10/2023, 11:44 AM
Firstly, you should wrap your mutable state with a
remember
. Secondly, I would suggest you to use an immutable list and when updating a certain item, create a copy of the original list with the item updated. And the of course, set that list state to that copy
f

faisalahmed

03/10/2023, 11:46 AM
@Vojtěch Hořánek Thanks for the response. I dont think
remember
is needed since this logic is sitting inside the
ViewModel.
About your suggestion, I think that will definitely work, but I just wanted to know why
MutableStateList<>
is not working the way it clearly mentions it willl?
v

Vojtěch Hořánek

03/10/2023, 11:47 AM
Oh, didnt notice it's inside a viewmodel
e

ephemient

03/10/2023, 11:47 AM
what you are doing is basically
for (i in list.indices) {
    if (list[i] == newMessage) {
        list[i] = newMessage
        break
you're setting it to an equal value, why do you expect anything to happen?
f

faisalahmed

03/10/2023, 11:51 AM
oh no no @ephemient If you see my code, the method
onMessageChanged
is lets supposed a method being triggered with new item coming from a data source. My code finds that specific item in the list, and then re-writes to that index.
s

Stylianos Gakis

03/10/2023, 11:54 AM
You are searching for the index of
newMessage
and then assign
newMessage
to it. You are assigning the same value to where it already was as ephemient suggests. If you were doing something like
val index = list.indexOf(newMessage.uniqueIdentifier)
then maybe it’d make sense, but now it does not. How does
Message
look internally? It may be that you have inner mutability in the message itself, meaning that compose won’t be able to see it change.
f

faisalahmed

03/10/2023, 11:58 AM
aaah, I found the issue guys. Thanks a lot @Stylianos Gakis and @ephemient . My
message
data class overrides
equalsTo
and uses a unique identifier to compare
messages
. Thats where my comparision is failing and no recompositions are triggered.