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.