https://kotlinlang.org logo
#compose
Title
# compose
t

Tash

10/19/2021, 12:16 AM
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

mattinger

10/19/2021, 12:19 AM
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

Albert Chang

10/19/2021, 12:43 AM
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

mattinger

10/19/2021, 12:57 AM
ok. my bad @Albert Chang you are correct.
remember makes sure it’s remembered across compositions, not config change.
t

Tash

10/19/2021, 8:07 AM
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

Adam Powell

10/19/2021, 1:45 PM
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

Tash

10/19/2021, 5:56 PM
Oh! I recall reading/watching something that explained how, under the hood, function parameters get treated as snapshot state…is that still true?
a

Adam Powell

10/19/2021, 5:59 PM
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

Tash

10/19/2021, 6:02 PM
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 🤦🏼
2 Views