If I make an interface of val properties, and implement it with a class that delegates these to a Compose State/MutableState, I'll not get the observability for Composable functions because, and the only way through is to expose State<T> instead of T, right?
Nope, that still works. Reads are tracked by actual calls to the getter of a State.value, no matter where or how it is called. Also, there’s no compiler magic here. I believe under the hood there is actually a thread local installed that points to the current snapshot and reads record themselves there. So it doesn’t matter what your call stack looks like.
So what actually happens when the following code is executed:
vartextbyremember{mutableStateOf("")}
1) A new object of the type MutableState<String> is created. This object holds the value (in our case empty string). And whenever the value changes, MutableState tells Android to recompose the UI.
2) Thanks to remember, the object of the MutableState is cashed and therefore will not get recreated every recomposition.
3) by tells the compiler to "link" var text with the value that the MutableState object holds. Whenever our text is updated, that value will be updated either automatically.
It really makes me wish they'd have an overload which just takes MutableState<String> so that I can just pass the state object itself, or some kind of adapter.
For whatever reason, Jetpack Compose seem to really love passing the value and the way to update the value as two different thingies, when they could have been bundled together as a single concept.
Top comments (7)
If I make an interface of
val
properties, and implement it with a class that delegates these to a ComposeState
/MutableState
, I'll not get the observability for Composable functions because, and the only way through is to exposeState<T>
instead ofT
, right?Nope, that still works. Reads are tracked by actual calls to the getter of a State.value, no matter where or how it is called. Also, there’s no compiler magic here. I believe under the hood there is actually a thread local installed that points to the current snapshot and reads record themselves there. So it doesn’t matter what your call stack looks like.
Oh, that's very neat!
Thanks for the info. I hope this knowledge makes it into the official docs.
So what actually happens when the following code is executed:
1) A new object of the type
MutableState<String>
is created. This object holds the value (in our case empty string). And whenever the value changes,MutableState
tells Android to recompose the UI.2) Thanks to
remember
, the object of theMutableState
is cashed and therefore will not get recreated every recomposition.3)
by
tells the compiler to "link"var text
with the value that theMutableState
object holds. Whenever ourtext
is updated, that value will be updated either automatically.🙏 Correct me if I'm wrong
There's also this form.
It really makes me wish they'd have an overload which just takes
MutableState<String>
so that I can just pass the state object itself, or some kind of adapter.For whatever reason, Jetpack Compose seem to really love passing the value and the way to update the value as two different thingies, when they could have been bundled together as a single concept.
"remembered values can be notified when they enter and leave a composition": can you give a pointer what you are referring to?
developer.android.com/reference/ko...