Reputation: 2072
In the code below, the TextField
that takes a mutableStateOf("")
works as expected: The TextField
shows whatever I type in.
However, if the TextField
takes StrHolder.s
as the value. The TextField
does not show anything I type. Why is that?
class StrHolder(var s: String)
Column {
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = { text = it },
)
var strHolder by remember {
mutableStateOf(StrHolder(""))
}
Text("My text is: ${strHolder.s}")
TextField(
value = strHolder.s,
onValueChange = { strHolder.s = it },
)
}
Upvotes: 0
Views: 485
Reputation: 10503
If you want Compose to know about changes to your StrHolder.s
property, you need to wrap it inside a State
. Like this:
class StrHolder {
var s by mutableStateOf("")
}
val strHolder by remember { mutableStateOf(Data()) }
TextField(
value = strHolder.s,
onValueChange = { strHolder.s = it }
)
Upvotes: 0
Reputation: 88132
In order for mutableStateOf
to trigger recomposition, the container value should be updated, e.g. strHolder = newValue
.
There's no way how it can know you've changed one of inner values.
data class
(with val
-only properties) is a great tool to be used in functional programming for such cases: copying the data will save your from such mistakes:
data class StrHolder(val s: String)
var strHolder by remember {
mutableStateOf(StrHolder(""))
}
Text("My text is: ${strHolder.s}")
TextField(
value = strHolder.s,
onValueChange = { strHolder = strHolder.copy(s = it) },
)
You can find more info about state in Compose in documentation, including this youtube video which explains the basic principles.
Upvotes: 1