I seem to get lost with `derivedStateOf` or maybe ...
# compose
o
I seem to get lost with
derivedStateOf
or maybe there is a bug. I have remembered derived state which basically gets parameter of a composable function (AnnotatedText) and produces a value from it, some other local mutable state (hover state) and some composition local (theme holding colors). The problem is that the derived state doesn’t produce change when composition local changes. If I remove
remember
it obviously recomposes, new instance is created and it works fine. But that means that it will recompose and recalculate the value whenever anything changes, which is rather expensive in my case. Do I miss something?
t
Does the derived state change when the other mutable state that it is derived from changes? I would imagine the composition local would have to be a "mutable state" to produce a corresponding change in the derived state when it changes
d
deriveStateOf
won't work on arbitrary variables in a composition. It only works on
mutableStateOf(...)
values. So if you read a
State
in a
deriveStateOf
, it'll subscribe to changes to it.
If you throw in a
rememberUpdatedStateOf
around the arbitrary variable, that might do what you want.
o
🤔 I thought composition locals should be “tracked” values as well, but probably that’s where my mental model was wrong… Now I need to read some explanation again 🙂
z
Composition local reads are tracked. So when you call
.current
, that call is tracked. But once you've read the local value, if you pass that somewhere else, it's just whatever value was in the local when it was read. If, for example, you capture the value in a memoized
derivedStateOf
lambda, you just capture the value, not the underlying snapshot state.
o
Uhm, so compose compiler transformations are not “introduce variable” tolerable? I would think the magic could be working here, so if you create a local value (in a composable context, of course) from a trackable reader, then it could make value also trackable, kinda transitive. No idea if it’s good or bad 🙂 Just finding it a bit too complex to track all the data flow…
z
The compiler doesn't have anything to do with the state tracking mechanism, and it definitely doesn't do anything like wrap things in snapshot states for you.
o
Is there a presentation or document of what compose compiler plugin is actually doing?
z
Lots, all over the place. Leland has written/given some, and there have been conference talks by other people as well.
o
Okay, will google it then
Offtopic: it’s funny how it turned around 🙂 In 2019 we discussed a bit of compose engine with Leland around the work of this guy https://www.umut-acar.org/publications on self-adjusting computations, DSLs and such. I was pushing for incremental computations in core Kotlin language at that time. It didn’t work out for numerous reasons, partially because compose was doing almost exactly that as a plugin and it was decided to be sufficient, and resources to do all the R&D were somewhere outside JetBrains 🙂 Now I’m using this technology and it is fantastic! Though not as magical as I envisioned 🪄
🎉 2