Normal Variable vs remember vs remember mutabableStateOf Comparisons

Normal Variable vs remember vs remember mutabableStateOf Comparisons

What is remember in Jetpack Compose? When and why do we want to use remember in a composable function?

ยท

3 min read

In composable function, you can declare variables in the following ways:

  • Normal variable
  • Variable with remember
  • Variable with remember mutableStateOf
// normal variable 
var countNormal = getInitValue()
// variable with rememer
var countRemember = remember { getInitValue() }
// variable with remember mutableStateOf
var countRememberMutableState by remember { mutableStateOf(getInitValue()) }

getInitValue() is used to demonstrate whether it gets called or executed during recomposition.

fun getInitValue(): Int {
    Log.d("RememberExample", "getInitValue() is called!")
    return 0
}

What exactly are the differences?

Normal Variable

If you make a change to countNormal, the variable is updated. However, it won't trigger recomposition. If there is recomposition occurs (triggered by others), this whole line var countNormal = getInitValue() is executed.

In other words, getInitValue() is called again and countNormal is reset back to 0. So countNormal is always 0 during recomposition.

remember Variable

It is similar to normal variable above. WhencountRemember is updated, it won't trigger recomposition. The difference is, during recomposition (triggered by others), it won't execute this whole line var countRemember = remember { getInitValue() }. Instead, it gets the cache version of getInitValue().

In other words, getInitValue() will NOT be called. The cached value is assigned to countRemember variable. Thus, this variable is always reset back to 0 too during recomposition.

remember mutableStateOf Variable

When countRememberMutableState is updated, not only this variable is updated, it also triggers the recomposition IF there are listeners (it is being used somewhere). Similar to remember variable above, it gets the cached version of MutableState and it won't call the mutableStateOf() again.

Since this cached version of MutableStateobject has already been updated, the value won't be 0 anymore. In other words, countRememberMutableState has the updated value during recomposition.

Code Example

This is a composable function example to demonstrate what I explained above.

@Composable
fun RememberExample() {
    var countNormal = getInitValue()
    var countRemember = remember { getInitValue() }
    var countRememberMutableState by remember { mutableStateOf(getInitValue()) }

    Column {
        Text(text = "countNormal: $countNormal")
        Text(text = "countRemember: $countRemember")
        Text(text = "countRememberMutableState: ${countRememberMutableState}")

        Button(onClick = {
            ++countNormal
        }) { Text(text = "++countWithoutRemember") }

        Button(onClick = {
            ++countRemember

        }) { Text(text = "++countWithRemember") }

        Button(onClick = {
            ++countRememberMutableState
        }) { Text(text = "++countWithRememberMutableState.value") }
    }
}

Summary

Here is the summary when we should use remember in my opinion.

normal variableremember variableremember mutableStateOf variable
Use this if you don't need to cache the variableUse this if your variable computation is expensive, thus you cache itUse this if you want to cache the created MutableState object which also allows you to trigger recomposition

Source Code

GitHub Repository: Demo_UnderstandComposeConcept

Did you find this article valuable?

Support Vincent Tsen - AndroidDev Blog by becoming a sponsor. Any amount is appreciated!

ย