Thread
#compose
    Tash

    Tash

    11 months ago
    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) ?
    // 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

    11 months ago
    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.
    Albert Chang

    Albert Chang

    11 months ago
    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

    11 months ago
    ok. my bad @Albert Chang you are correct.
    remember makes sure it’s remembered across compositions, not config change.
    Tash

    Tash

    11 months ago
    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:
    // 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")
    }
    Adam Powell

    Adam Powell

    11 months ago
    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. 🙂
    Tash

    Tash

    11 months ago
    Oh! I recall reading/watching something that explained how, under the hood, function parameters get treated as snapshot state…is that still true?
    Adam Powell

    Adam Powell

    11 months ago
    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
    Tash

    Tash

    11 months ago
    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 🤦🏼