Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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("")
like image 899
Ahmed M. Abdalla Avatar asked Feb 12 '21 09:02

Ahmed M. Abdalla


People also ask

What does remember do in jetpack compose?

remember can be used to store both mutable and immutable objects. Note: remember stores objects in the Composition, and forgets the object when the composable that called remember is removed from the Composition.

What is Mutablestateof in jetpack compose?

If you want to change the state of TextField and also update the UI, you can use a MutableState . Compose observes any reads and writes to the MutableState object and triggers a recomposition to update the UI.

What is LazyColumn in jetpack compose?

A LazyColumn is a vertically scrolling list that only composes and lays out the currently visible items. It's similar to a Recyclerview in the classic Android View system.

What is scaffold in jetpack compose?

Scaffold provides a slot for a floating action button. You can use the floatingActionButton slot and a FloatingActionButton : Scaffold(


3 Answers

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 triggers 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("")

If you are doing the above, you are just creating a MutableState object without remembering it.

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.

like image 50
ckunder Avatar answered Oct 20 '22 19:10

ckunder


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

like image 13
vitidev Avatar answered Oct 20 '22 20:10

vitidev


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.

like image 5
Android Developer Avatar answered Oct 20 '22 19:10

Android Developer