https://kotlinlang.org logo
#compose
Title
# compose
a

Archie

07/26/2020, 2:58 PM
Lets say I have this code:
Copy code
@Composable
fun Greetings() {
    val state = state { "Hello" }
    Column {
        Text(text = state.value)
        Button(onClick = {
            state.value = "Hello"
        }) {
            Text(text = "Greet!")
        }
    }
}
Notice that the initial value of state is "Hello" and whenever the Button is clicked, it sets the value of the state to the same value (
state.value = "Hello"
). Does this trigger recomposition? or recomposition is only triggered when
state
is set with a different value? Also is there a hook or callback I could attach to see how recomposition works in
compose
?
a

Adam Powell

07/26/2020, 3:02 PM
It depends on the policy you set on the state object at construction. It defaults to reference equality not triggering recomposition.
😮 1
You can also use a structural equality policy if you prefer and it'll use
.equals
As for a hook or callback, which part are you looking for? the actual recomposition process or how snapshot invalidation notifies other parts of the system?
a

Archie

07/26/2020, 3:16 PM
It depends on the policy you set on the state object...
I see so thats whats it for..
As for a hook or callback, which part are you looking for?
hmmm... now im interested in both...
(the FrameManager name outlived the "frames" system so far 🙂 )
If you want to be able to track state reads/writes/commits in the same way that a composition does, the FrameManager source shows how
that step eventually causes a composer to invalidate itself with the recomposer (this step will probably be folded into individual root compositions rather than the shared recomposer down the road, still working on this part)
which wakes up the recomposer's main loop, it awaits a frame, then runs all pending recompositions between when android's input phase and view traversal phases happen
then the usual view measure/layout/draw steps kick in
a

Archie

07/26/2020, 3:35 PM
Thank you soo much this is very informative.
Last question, is there a reason why the default policy set for state is
referentialEqualityPolicy
and not
structuralEqualityPolicy
?
r

romainguy

07/26/2020, 4:42 PM
For callbacks you can use onActive/onDispose/onCommit
a

Adam Powell

07/26/2020, 4:51 PM
re. the default policy, not a super definitive one. StateFlow deciding on distinctUntilChanged behavior out of the box might sway us in a different direction, we need to do some additional measurements.
👍 1
discussion around this involves a few factors, among them are the potential cost of structural equality comparisons for very deeply nested data class trees, especially considering that composition skipping will do the same comparisons during recomposition for stable types
it should never affect correctness of the resulting composition since state changes are always idempotent, but it can have deeper performance implications
a

Archie

07/26/2020, 5:01 PM
i see thank you very much
👍 1
r

romainguy

07/26/2020, 5:22 PM
In this particular case string interning should take care of the equality test :)
a

Archie

07/26/2020, 5:28 PM
@Adam Powell May I ask some clarifications, by:
it should never affect correctness of the resulting composition since state changes are always idempotent
are you pertaining to my example or is it something else?
@romainguy for this example yes. But I was also thinking about when the
state
is an object rather than it just being a string.
a

Adam Powell

07/26/2020, 5:36 PM
Not specific to any one example; the same composition for the same input state should produce the same results. If the same state object is set to equivalent but referentially-unequal values several times, it should not change the appearance or behavior of the composition. At worst it will do a little extra work to arrive at the same result.
❤️ 1
a

Archie

07/26/2020, 5:37 PM
Ah yes! Thank you very much!
4 Views