Why recomposition is happening in this Composable ...
# compose
s
Why recomposition is happening in this Composable on “isLiveText” property change? should nt. it be happening just in “AnalyzedText” Composable where its read, this is causing whole Composable to Recompose and I do not want “ScanPreview” to recompose on “isLiveText” property change? Thread in Slack Conversation
now its even recomposing ScanPreview on recognizedText state change, but its’not read in ScanPreview ?😥
k
you might be able to work around it by wrapping
isLiveText
in a state to prevent recomposition.
But your code should not be dependent on how compose decides to run it.
1
z
Agreed with previous messages, how compose decides to recompose things should not affect the correctness of your code. That said, it can still be helpful to understand what’s going on.
isLiveText
isn’t a property here, it’s just a parameter, so it’s definitely not a delegate and won’t use the snapshot state read tracking system that
MutableState
uses. Whenever
ScanScreen
is called, if any of its parameters are different than the last call, its body will be re-executed. As part of that reexecution, and composables to which you’ve passed lambdas which capture that property will also be recomposed, since the lambda objects need to be recreated to capture the new value. As for
recognizedText
, the reason that
ScanPreview
gets called whenever it changes is trickier. If
Box
were a normal, non-inlined function, it would still get called because
ScanPreview
is called from the recompose scope that is delimited by the lambda you’re passing to
Box
.
recognizedText
is read in that same recompose scope, in order to pass its value to
AnalyzedText
. So when the state changes, that recompose scope (ie that lambda) is re-executed. However,
Box
is actually an inline function, which means it doesn’t get its own recompose scope, which means that any state read inside `Box`’s lambda will actually cause all of
ScanScreen
to recompose anyway. It’s important to note that compose doesn’t try to re-execute only parts of functions. If a state changes that is read in a given recompose scope, that entire recompose scope is recomposed. Also important to remember that values passed to functions are calculated in the bytecode of the calling function. If you call
println("hello" + "world")
, that string concatenation is effectively performed in the line before
println
, in the calling function. That means that if you pass the value of a snapshot state object to a function, that state read is recorded in the calling recompose scope, not the one of the function the value is being passed to.
s
thanks for this explanation, I was using State data holder too much where I should not be using for a reactive UI which indeed was resulting in recomposition of Composables which I don’t want .
z
FWIW, I ended up writing a blog post with a more in-depth explanation
s
Thanks for the detailed post, loved it.