I apologize if this has been asked already, but wa...
# compose
t
I apologize if this has been asked already, but wanted to double check here. what are the effective differences between the two (apart from one being a composable function) ?
Copy code
// Using derivedStateOf
fun nameA(name: String): State<String> {
    return derivedStateOf { "Hello $name" } 
}

// Using rememberUpdatedState
@Composable
fun nameA(name: String): State<String> {
    return rememberUpdatedState("Hello $name")
}
m
Technically any State implementation can be used outside of the compose world. It’s highly suitable for view models to replace LiveData i believe. By adding a “rememberUpdatedState”, you’re now tying the internally created state object to the composition context so that when configuration changes like rotation happen that require rebuilding the entire view, the state gets remembered and repopulated.
derivedState is simply a calculation off of some other state. When you read the value, it may get recomputed if there’s some other piece of state it depends on.
at least that’s my understanding of it.
a
derivedStateOf
only runs the calculation when the states (
name
here) read in the lambda change.
rememberUpdatedState
runs the calculation on every recomposition. Also if you are using
derivedStateOf
in a composable function, you should always
remember
it.
@mattinger That is not how
rememberUpdatedState
behaves. You are probably talking about
rememberSavable
.
m
ok. my bad @Albert Chang you are correct.
remember makes sure it’s remembered across compositions, not config change.
t
derivedStateOf
 only runs the calculation when the states (
name
 here) read in the lambda change. 
rememberUpdatedState
 runs the calculation on every recomposition
important distinction 👍🏼 so basically, with usage we’re looking at:
Copy code
// Using derivedStateOf + usage
@Composable
fun Content(name: String) {
    val greeting by remember { greeting(name) }
    Text(greeting)
}

fun greeting(name: String): State<String> {
    return derivedStateOf { "Hello $name" } 
}

// Using rememberUpdatedState + usage
@Composable
fun Content(name: String) {
    val greeting by greeting(name)
    Text(greeting)
}

@Composable
fun greeting(name: String): State<String> {
    return rememberUpdatedState("Hello $name")
}
a
Your derivedStateOf example probably doesn't do what you're intending it to do above. derivedStateOf is invalidated when snapshot state it reads is invalidated, and parameters aren't snapshot state.
What you have there is an expensive string. 🙂
t
Oh! I recall reading/watching something that explained how, under the hood, function parameters get treated as snapshot state…is that still true?
a
now I'm curious where you heard that from, if that were the case we wouldn't need
rememberUpdatedState
🙂
we debated quite a bit about this decision and how lambda capture updates like this should happen/be allowed, and we chose to be more explicit and more closely match how Kotlin behaves elsewhere
t
let me try to find that…it could also very well be that i misunderstood whatever it was 🙈
we debated quite a bit about this decision and how lambda capture updates like this should happen/be allowed, and we chose to be more explicit and more closely match how Kotlin behaves elsewhere
ah, I see. makes sense 👍🏼
So it seems like
fun greeting
that uses
derivedStateOf
won’t actually be doing anything…just just going to create the string once…and thats it…
however the second
fun greeting
with
rememberUpdatedState
will ensure that the returned state will always contain the latest
name
that the function was called with
just remembered, I had originally confused myself as to how function calls + their parameters are handled in the slot table, vs how snapshot states are handled 🤦🏼