What's the difference between `rememberUpdatedStat...
# compose
b
What's the difference between
rememberUpdatedState
,
remember
and
rememberSaveable
in Android? I've gone through the docs but don't understand properly when to use each. I know
rememberSaveable
persist state across configuration changes Can anyone please suggest some use cases? Also, does
rememberUpdatedState
persist state across configuration changes?
s
rememberUpdatedState has nothing to do with persisting things accross config changes. The docs that explain the use case the best are here https://developer.android.com/develop/ui/compose/side-effects#rememberupdatedstate. But if this is too confusing to you, I think you can initially get away with not using it in the beginning before it starts making sense. I do remember it was a while before I properly understood what it does from when I started with compose.
Here is one example with it https://kotlinlang.slack.com/archives/CJLTWPH7S/p1678750942883689?thread_ts=1678732457.665529&cid=CJLTWPH7S And here is another where rememberUpdatedState fixes one bug https://kotlinlang.slack.com/archives/CJLTWPH7S/p1640285517040200?thread_ts=1640270959.029600&cid=CJLTWPH7S The tl;dr that made it click for me is that
rememberUpdatedState
turns
T
into
State<T>
. But I understand how this can be tricky by itself
z
remember
is a fundamental primitive of the compose runtime. •
rememberSaveable
extends that primitive with support for a pluggable state persistence mechanism that requires support from the hosting app toolkit . •
rememberUpdatedState
is just a convenience function for a certain pattern that’s useful to save a few lines of code in certain cases.
1
m
Just in case a different point of view helps, another way to look at it is what they are used for: [disclaimer: I've been using Compose for a bit less than a year, so it's possible I may have some minor inaccuracies here] 💁
remember
Use
remember
when you want something to survive recomposition (instead of making a new instance with each recomposition). Note that if the
remember
call leaves and re-enters the composition, you'll still get a new instance. 💁
rememberSaveable
Use
rememberSaveable
when you want something to survive recomposition and certain kinds of platform-specific potential state loss. This depends very much on the platform app toolkit. For example, Android provides a mechanism for saving state in a Bundle so it can survive a process getting killed and re-created when the system is low on RAM, or survive activity re-creation (such as for some kinds of configuration changes). For some platforms (I think!) this might just do the same thing as
remember
. Use
rememberSaveable
to save ephemeral state like the scroll position of a list or the cursor position in a text field. Don't use
rememberSaveable
for things that are affected by configuration changes, unless you have a separate way to handle those configuration changes yourself. For example, you probably don't want to use
rememberSaveable
for things like localized UI strings, because you want those to be re-created with the correct values when (for example) the user changes the system language. 💁
rememberUpdatedState
This is very different from the others. The most common use for this when you have a lambda that sticks around over recompositions, but you want the latest value (not the one captured by the lambda). For example, this is very useful together with
.pointerInput
if you are handling a gesture that might affect the composition during the gesture: The pointer input lambda can't be re-created mid-gesture or you lose the gesture tracking, but it might need to access the latest values of state that change as a result of that gesture. As Zach said, it's a convenience function. You can look at the implementation of it yourself to see how it works (from Android Studio or Idea, it's easy to jump into to the source code for any of the compose APIs...if you're not already doing it, it's a great way to learn how compose works):
Copy code
@Composable
fun <T> rememberUpdatedState(newValue: T): State<T> = remember {
    mutableStateOf(newValue)
}.apply { value = newValue }
As you can see, it's just 4 lines of code! All it does is remember a
State
and then update that
State
with the latest value whenever there's a recomposition, so that if you capture it in a lambda, you're getting the latest value instead of the value when the lambda was created.
👍🏻 1
👍 1