How to update UI when setting object's field

data class Y(
    var s: Boolean
)
@Composable
fun StartButton(
//    coroutineScope: CoroutineScope,
//    subscription: Subscription
) {
    val y by remember { mutableStateOf(Y(false) )}
    log.info { "y.s ${y.s}" }
    if (y.s) {
        Button(onClick = {y.s = false}) {
            Text("true")
        }
    } else {
        Button(onClick = {y.s = true}) {
            Text("false")
        }
    }
}

When button is pressed, nothing happens. No recompose, no ui update, no nothing.
What’s the right way to use a data class as mutableState and set it’s field?

I’m no Compose expert, so take what I say with a grain of salt. :stuck_out_tongue:

I think you have to extract y.s into its own variable, then use that variable inside remember { mutableStateOf(localS) }. Then, when the button is clicked, you mutate the localS and mutate y.s. I think Compose isn’t smart enough to track changes to an object.

Yes, after a whole night’s digging, I found you are right. we should always use MutableState on what we want to change and update UI. Change a value inside a ref won’t cause recompose.

1 Like

One option is to not to make data class mutable, use copying instead:

data class Y(val s: Boolean)

Button(onClick = {
	y = y.copy(s = false)
})
2 Likes