I have: ```class ScreenAState { val people = m...
# compose
c
I have:
Copy code
class ScreenAState {
    val people = mutableStateListOf<PersonUIWrapper>()
}

data class PersonUIWrapper(var selected: Boolean, val person: Person)
then in an onclick of a person in my list I do
Copy code
TextButton(onClick = {
    it.selected = true
})...
but my code doesn't recompose, and therefore doesn't show a checkmark. Is my PersonUIWrapper supposed to use snapshot state internally for it's two fields?
j
What does “it” in your onClick refer to? the onClick lambda parameter for TextButton looks like it doesn’t take an argument.
I’m assuming it’s supposed to refer to your PersonUIWrapper, but not clear on how it’s referring to it from this code snippet.
c
Copy code
vm.state.people.forEach {
    TextButton(onClick = {
    it.selected = true
}) {
👍 1
j
Are you passing in it.selected to the checkbox as the checked state?
or rather the PersonUIWrapper.selected value. May not be in the same forEach
c
Copy code
if (it.selected) {
    Icon(Icons.Default.Check, null)
}
Text(text = it.person.name)
👍 1
So the full thing becomes
Copy code
vm.state.people.forEach {
    TextButton(onClick = {
    it.selected = true
}) {
if (it.selected) {
    Icon(Icons.Default.Check, null)
}
Text(text = it.person.name)
}
Sorry for providing it in pieces. I was trying to be as concise as possible. 😄
j
gotcha. That looks like it should work from my knowledge. Unfortunately, I’m fairly new at this.
My understanding is any access to the mutable state should be recorded and marked for recomposition when it changes
c
Yeah. Just when I thought lists in compose made sense...
j
my only suspicion is that you may need a list of mutableState<PersonUIWrapper> instead of a mutableStateListOf
I’m thinking maybe the mutableStateList will recompose on changes to the list itself rather than changes to the internal state of the values in the list
I haven’t used mutableStateListOf, though so that’s just a hunch
mutableStateListOf
can only notify about adding/removing/replacing some element in the list. When you change any class inside the list, the mutable state cannot know about it.
👍 1
a
To partially answer your original question, if
PersonUIWrapper
was backed by state that was observable to Compose (like
mutableStateOf
), then this would work like you’d expect. And that can be preferable as an alternative to the
.copy
solution with a
data class
.
🤩 1
c
Cool. I moved to this with Alex's rec
Copy code
class PersonUIWrapper(val selected: MutableState<Boolean> = mutableStateOf(true), val person: Person)
It kind of sucks that I can't use
by
in this case, but using
.value
isn't the worst thing!
a
seems you're looking for
Copy code
class PersonUIWrapper(
  selected: Boolean,
  val person: Person
) {
  var selected by mutableStateOf(selected)
}
👍 1
c
Safe to say that I wouldn't have come up with that on my own. Thanks adam. I'm still not 100% with Kotlins constructor syntax, but I guess this just defines a constructor arg and uses that constructor arg to create a property?
a
Yep
If you read Kotlin's primary constructors like a function where the class body is the function body then it makes a lot of things fall into place
👍 3