Ahmed Bakhet
Ahmed Bakhet

Reputation: 3234

What is the difference between "remember" and "mutableState" in android jetpack compose?

I'm new in jetpack compose and trying to understand the difference between remember and mutableStateOf


In other words the deference between this line

val text = remember{ mutableStateOf("") }

and this

val text = remember{ "" }

and this also

val text = mutableStateOf("")

Upvotes: 107

Views: 55815

Answers (7)

Oumaima Makhlouk
Oumaima Makhlouk

Reputation: 624

  • Remember : stores value only during recomposition
  • mutableStateOf : triggers recomposition when changed

Upvotes: 0

ckunder
ckunder

Reputation: 2300

remember is a composable function that can be used to cache expensive operations. You can think of it as a cache which is local to your composable.

val state: Int = remember { 1 }

The state in the above code is immutable. If you want to change that state and also update the UI, you can use a MutableState. Compose will observe any reads/writes the MutableState object and trigger a recomposition to update the UI.

val state: MutableState<Int> = remember { mutableStateOf(1) }

Text(
   modifier = Modifier.clickable { state.value += 1 },
   text = "${state.value}",
 )

Another variant (added in alpha12) called rememberSaveable which is similar to remember, but the stored value can survive process death or configuration changes.

val state: MutableState<Int> = rememberSaveable { mutableStateOf(1) }

Note: You can also use property delegates as a syntactic sugar to unwrap the MutableState.

var state: Int by remember { mutableStateOf(1) }

Regarding the last part of your question:

val text = mutableStateOf("")

MutableState is an alternative to using LiveData or Flow. Compose does not observe any changes to this object by default and therefore no recomposition will happen. If you want the changes to be observed and the state to be cached use remember. If you don't need the caching but only want to observe, you can use derivedStateOf. Here is a sample of how to use it.

As pointed out by Ahmad Hamwi in the comments and quoting them:

Compose does observe the value of the state, in fact there's a @Stable annotation on top of it, and that's its sole responsibility, but since we're not remembering the state, a mutableStateOf(1) will always be created AGAIN, so there will be a new instance of a state, but will still have the same value of 1. So the state seems to not change, but there IS a recomposition happening.

Upvotes: 141

USMAN osman
USMAN osman

Reputation: 1030

mutableStateOf(): it's an observable that observes the values when underlaying values gets changes and updates the UI. like we use liveData and stateFlows but LiveData also has lifecycle mechanism and almost same goes with StateFlows.

remember{}: It persists the data across the recomposition.
what is recomposition? When the state get changes, the composable that holds that value recomposes itself to give us updated value.
for example: we have a textView(composable) that observes the value, right now which is 1. We press the button and increment the value with 2. What happens here when the value goes from 1 to 2 the textView(composable) recreates(recomposes) itself and shows us the updated value which is 2, this is known as recomposition.

when we use this: val text = remember{ mutableStateOf("") } that's means we are not only observing the data but also persisting the data across the recomposition.

Upvotes: 8

Android Developer
Android Developer

Reputation: 9643

If remember is used with a field it's value will persist across recompositions.

If mutableState is used with a field, all the composables which are using that field will be recomposed whenever the field values changes.

Upvotes: 14

vitidev
vitidev

Reputation: 980

As i understand.

remember just cache result of computation to keep result instance between compositions. Any object. And MutableState instance. And this is why it is useful.

val text = remember{ "" }

just cache empty string.

val text = mutableStateOf("")

create MutableState and compose observe it value, but not cache MutableState instance, so it will be re-created on next recomposition (of course if recomposition will happen in this place)

for example:

val state: MutableState<Int> =  mutableStateOf(1)
println(state.toString())
Text(
    modifier = Modifier.clickable { state.value += 1 },
    text = "${state.value}",
)

the text will always be 1, because every recomposition re-creates state and the output will be:

MutableState(value=1)@227069120
MutableState(value=1)@104526071
MutableState(value=1)@915621104
MutableState(value=1)@580489706 

remember caches MutableState object and keep same instance on every recomposition

val state: MutableState<Int> = remember { mutableStateOf(1) }
println(state.toString())
Text(
    modifier = Modifier.clickable { state.value += 1 },
    text = "${state.value}",
)

work as expected.

MutableState(value=2)@1121832406
MutableState(value=3)@1121832406
MutableState(value=4)@1121832406
MutableState(value=5)@1121832406

remember(key)

val key = remember { 0 }
var state by remember(key) { mutableStateOf(1) }
println(state.toString())
Text(
    modifier = Modifier.clickable { state += 1 },
    text = "${state}",
)

Works like the example above, even though the key doesn't change. It's because in case of a MutableState, not the value is cached, but the instance of MutableState itself with the value field, which changes.

changing key value will recreate MutableState instance

Upvotes: 27

djacobsen13
djacobsen13

Reputation: 259

The remember keyword can store a mutable or an immutable object. If you pass mutableStateOf to remember, any time the value of that object changes, it will force recomposition of the composables that are reading that value.

Upvotes: 2

Code Poet
Code Poet

Reputation: 7975

Basically, in the first example you are storing a mutable value and in the second you are storing an immutable value.

According to the doc: "You can store immutable values when caching expensive UI operations, such as computing text formatting. The remembered value is stored in the Composition with the composable that called remember." Source

For more info on mutableStateOf, here is the doc link. You use this when you want your UI the be recomposed when there is a change in your values.

Upvotes: 3

Related Questions