Having something like this: `fun someComposable(e...
# compose
m
Having something like this:
fun someComposable(enabled: Boolean){
var valueField by remember{
mutableStateOf(..)
}
val errorInternal: Boolean = remember(enabled, valueField) {
derivedStateOf(valueField && enabled)
}
}
I need a state that depends on another state and a variable. derivedStateOf is for state only. This works but is this the correct approach?
c
maybe wrap that other variable in
rememberUpdatedState()
? Putting
derivedStateOf
in a
remember { }
block seems wrong to me, though I can't really articulate why...
m
Like this:
fun someComposable(enabled: Boolean){
var valueField by remember{
mutableStateOf(..)
}
val _enabled = rememberUpdatedState(enabled)
val errorInternal by derivedStateOf(valueField && enabled)}
}
c
Yeah, I think that would work. Alternatively, since the value you're calculating for
errorInternal
is fast, you probably don't need to do that at all.
derivedStateOf
is more of a cache for expensive operations that depend on state values, rather than a requirement for computations based on state values. there's nothing wrong with computing simple values directly within the composable function
m
ya but that value is used in the setup of another composable. Would that cause that composable to recompose ?
c
Yes, it should, Compose is smart about that. It's more that the State variables tell Compose when to recompose, but it still checks each @Composable function individually based on the current values (whether State or not) to know what to recompose
m
that’s one of the biggest confusions for me. There are cases i’m in doubt whether to use a state or a simple variable
c
I'd suggest starting with the assumption you want normal variables for everything, keep writing the same type of code you'd write elsewhere in the non-Compose world. You shouldn't need to drop down to Compose/State-specific APIs unless you actually find that to be causing issues (things not recomposing when you expect, performance concerns, etc.).
a
I would alway start with the simplest code by just computing the value directly:
Copy code
fun someComposable(enabled: Boolean){
	var valueField by remember {
		mutableStateOf(...)
	}
	val errorInternal = valueField && enabled
}
Casey is exactly right that
derivedStateOf
is a caching mechanism. It has its uses for fine-tuning when things recompose, but you shouldn’t really need to do that tuning unless you have a noticeable performance reason to do so. Just like any other caching mechanisms, you have to be more careful to invalidate the cache at the right time to see a tangible benefit without having subtle state issues
z
And if you do end up using
derivedStateOf
from a composition directly, you definitely need to put it in a
remember
otherwise you’re re-creating the state every time, just like if you use
mutableStateOf
without a
remember
.
☝️ 1
l
Note that
derivedStateOf
itself seems to be quite heavy to me. Also derivedStateOf can be used outside Compose. Thinking if something can be used outside Compose is also a great criteria like:
Copy code
class Model {
    val a by mutableStateOf { 1 }
    val b by derivedStateOf { a - 3 }
}
States (and snapshot-related apis) are not that compose-specific. In fact I use them to manage states out of Compose.