Stylianos Gakis
01/12/2022, 5:02 PMderivedStateOf
for when we want to calculate some result using composable’s parameters vs using local mutableState objects. More in thread 🧵Stylianos Gakis
01/12/2022, 5:02 PMresult
I’d call derivedStateOf
and OtherComp
will only be called when result actually changes.
@Composable
fun Comp() {
var one by remember { mutableStateOf(5) }
var two by remember { mutableStateOf(8) }
val result: Boolean by remember { derivedStateOf { one * two < 10 } }
OtherComp(result) // Pass the result whatever composable
}
But if items come as parameters, and considering this comment in the documentation mentioning that derivedStateOf only works with State
in this next example we don’t have state but normal parameters. So how do I do the same behavior now?
@Composable
fun Comp(one: Int, two: Int) {
val result = ??
OtherComp(result)
}
If I just do val result = one * two < 10
it will work fine, but if the Comp
composable had more parameters (say three: Int
, and it changes but not one
or two
, result
will be re-calculated for no reason since it happens in every recomposition of Comp
(especially bad since I have another variable coming from an animation which changes rapidly)
Doing just val result = derivedStateOf { one * two < 10 }
seems to also be wrong according to this since it will also be recreated on every recomposition since we’re not remembering it.
Doing then instead val result = remember { derivedStateOf { one * two < 10 } }
doesn’t work at all as remember has no keys and derivedStateOf doesn’t know when its inputs change since one
and two
are not state objects.
Finally doing val result = remember(one, two) { derivedStateOf { one * two < 10 } }
kind of defeats the purpose of derivedStateOf since we’re keying everything ourselves so we might as well then go with val result = remember(one, two) { one * two < 10 }
? So is this the way to do things when we want to “reduce” some input to some result when that input comes from the function parameters?curioustechizen
01/12/2022, 5:07 PMval result = remember(one, two) { one * two < 10 }
here? Aren't those keys to remember
meant for this exact use case?Stylianos Gakis
01/12/2022, 5:13 PMderivedStateOf
“.
Also result now no longer is a State object, as derivedStateOf
would give. but it’s a normal Boolean. Not sure if this has any other implications as wellZach Klippenstein (he/him) [MOD]
01/12/2022, 10:29 PMrememberUpdatedState
for parametersStylianos Gakis
01/12/2022, 10:51 PMrememberUpdatedState
basically turns a T
into State<T>
in a sense right?
Then it becomes this I assume:
@Composable
fun Comp(one: Int, two: Int) {
val updatedOne by rememberUpdatedState(one)
val updatedTwo by rememberUpdatedState(two)
val result: Boolean by remember { derivedStateOf { updatedOne * updatedTwo < 10 } }
OtherComp(result)
}
Which becomes quite some ceremony over just
@Composable
fun Comp(one: Int, two: Int) {
val result: Boolean = one * two < 10
OtherComp(result)
}
And I guess at that point it’s a decision making point for the dev if it is worth it in the context, hmm a tough choice imo 🤔Zach Klippenstein (he/him) [MOD]
01/13/2022, 1:12 AMlhwdev
01/13/2022, 5:15 AMderivedStateOf
can be used for more fine-grained recomposing. In your case, just use remember(one, two) { ... }
or just val result = one * two < 10
. If you need to pass some state as-is deep down the tree, and only recompose ones that read that state, (via state.value
or delegation + reading that variable) use states.
If you need to pass the value rather than State<?>
, using state here is no help. Recomposing is quite smart.
Note that derivedStateOf
can be used outside Compose, and states are not that Compose-specific.