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

Colton Idle

01/21/2022, 7:23 AM
I've read Zach K blog posts on the topic but I'm still encountering a situation that I can't seem to untangle. Essentially I have a list of items. This list is a mutableStateList. Every item could also have a single property that is also mutableState. When I update this item mutableState, I don't see the composable recompose. Can anyone spot any egregious issues here?
Copy code
class ScreenViewState {
  val list = mutableStateListOf<Item>()
and my Item
Copy code
class ConcreteType(override val type: String = "") : Item {
    var something by mutableStateOf("beep")
then in my VM I call
Copy code
(myItem as ConcreteType).something = "boop"
My composable always beeps, but never boops.
k

KamilH

01/21/2022, 7:32 AM
When you change the underlaying
var
, you doesn’t actually mutate the list. Make your `ConcreteType`’s property not mutable and when you want your composable to recompose,
replace
the value on the list. I think having
MutableList
of
mutableStateOf
can be called “2 degrees of mutability” that has been described by Zach in mentioned blog post
c

Colton Idle

01/21/2022, 7:44 AM
Yeah, that did cross my mind with having a mutable state inside of a mutable list, but I only felt fine with it because Adam Powell (and others) kinda led me towards this path for another similar case where I had a mutable list of people, and each person had a mutable state of "isChecked". And so that use case seemed valid in that thread, and so I could only think that my use case here is valid? Prev thread: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1637203859164500?thread_ts=1637187114.148800&amp;cid=CJLTWPH7S
k

KamilH

01/21/2022, 7:52 AM
In the previous example you did this:
Copy code
vm.state.people.forEach {
    TextButton(onClick = {
    it.selected = true
})
so for each
people
you put
TextButton
, do you do the same in current example? Or maybe you put your items in the
LazyColumn
for example?
c

Colton Idle

01/21/2022, 8:01 AM
Hm. You might be onto something there. In the current example I only do what you see above in the original question. I'm trying to edit directly. What's intersting is that I don't actually technically need the original list to be a mutableStateListOf, so I switched over to
Copy code
val list = mutableListOf<Item>()
and so that only leaves me with mutableState inside of the ConcreteType and it still does not work.
Okay. Even went ahead and converted my list to
Copy code
var list = listOf<Item>()
and it still Beeps. No boops.
its like something about mutableStateOf in a polymorphic type isn't supported maybe?
😭 It was user error. I had a rogue parent that had a remember function surrounding my actual composable. Things seem to be updating now. I'm going to revert and do a bunch of sanity checks to try out the two degrees of mutability thing.
Every variation that we talked about above ended up working. no issues with the 2 degrees of mutability sort of thing. i assume because it wasn't exposing multiple ways to mutate the single list (mutable within a mutable) and this was moreso that I had a mutable list, with non mutable elements, that had mutable properties? either way. Thank you @KamilH for rubberducking.
k

KamilH

01/21/2022, 9:12 AM
I’m glad you found where the problem is
z

Zach Klippenstein (he/him) [MOD]

01/21/2022, 4:34 PM
It's fine to mutate objects' properties inside a list if those properties are backed by mutable state. I'm not sure how you even managed to get a composable inside a remember function, that shouldn't even compile 😅
2 Views