Ihor Levkivskyi
Ihor Levkivskyi

Reputation: 391

When to use remember in Android Compose

On the official site, there is no exact information, on what cases we should use "remember{}".

  1. Should we remember arithmetical operations if they repeat multiple times in the code? Or if it is only one operation but very complex?

  2. Also what about the classes of Android Compose - RoundedCornerShape, TextStyle, BorderStroke, SolidColor, FocusRequester, KeyboardActions, KeyboardOptions, Gradient? When we use it while creating an object(ex. RoundedCornerShape(10.dp)) multiple times (in different places in the code or the cycle(creates multiple objects in the same composable functions)? Does it make sense to remember these objects while single using?

  3. When we make some transformation with a list of data, mapping smth?

How to know when it is useful for caching while recomposition and when it is redundant?

Upvotes: 5

Views: 7675

Answers (3)

Devrath
Devrath

Reputation: 42824

  • remember usually tells the compiler that the compose will have to remember the value passed to it.
  • Because if it does not remember it, it will execute the lambda on every recomposition

Example:

@Composable
fun rememberSnackBarState(): SnackbarState {
    return remember { SnackbarState() }
}

class SnackbarState {

    var success by mutableStateOf<String?>(null)
        private set

    var error by mutableStateOf<Exception?>(null)
        private set

    private var updated by mutableStateOf(false)

    fun addSuccess(message:String){
        error = null
        success = message
        updated = !updated
    }

    fun addError(exception: Exception) {
        success = null
        error = exception
        updated = !updated
    }

}

Usage:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageBarComposeTheme {
                val state = rememberSnackBarState()
               
            }
        }
    }
}

Upvotes: 0

F.Mysir
F.Mysir

Reputation: 4126

SHORT ANSWER:

You use remember in Android Compose when you want to remember the value.

LONG ANSWER:

The mechanism works as follows when a state variable changes then recomposition is triggered, and you see the updated screen on your mobile.

For example:

Case 1

@Compose
fun MyComposable(){
    var text: String = ""
    TextField(
        value = text,
        onValueChange = { newText ->
            text = newText
        }
}

In this case: when you press a button on your keyboard nothing is happening because you do not have a state value that compose mechanism looks in order to update your screen. In this case when you press a letter on your keyboard nothing happens at all.

Case 2

@Compose
fun MyComposable(){
    var text by mutableStateOf("")
    TextField(
        value = text,
        onValueChange = { newText ->
            text = newText
        }
}

In this case you have a state variable (in our case a string), and when you press a button on your keyboard recomposition is happening. So the mechanism says hey look the value has changed, let me recompose the screen with this composable then the block runs again, and text variable defaults to an empty string("") again. So even though recomposition happened you see the same thing on your screen.

Case 3

@Compose
fun MyComposable(){
    var text by remember { mutableStateOf("") }
    TextField(
        value = text,
        onValueChange = { newText ->
            text = newText
        }
}

In this case lets say you want to type the number 10 on your keyboard. You click 1 mechanism sees the state value has changed. Then mechanism executes composable function again when at text value it does not default it to "" but keeps or remembers the 1 you pressed before. So you see 1 on your screen and you can press 0 and see 10 finally...

So when is useful to use remember? Since the block of a composable may run several times and in unexpected ways, you should use a remember{} when you want your variable to survive this re-execution of code. In other words if you have a constant value you do not care and you do not want to remember it. On the other side if you want an animation to happen you want the value to be remembered between two points so remember should be use. For complex calculations of course it is better to transfer this code to a ViewModel as stated from @nglauber.

Upvotes: 10

nglauber
nglauber

Reputation: 23894

Here is my understanding about remember...

  1. You should use remember for values you want to be remembered across recompositions. I don't think that simple math operations worth it to be remembered and complex operations should be done on other parts of the app like a View Model or Use Case (preferably in a separate thread).

  2. Let's break up this question in parts:

    2.1. Shapes, Colors and TextStyles should be declared in your theme. See this article how to do this. Therefore, you wouldn't need to remember.

    2.2. The object KeyboardOptions is not kept in memory. It is converted to IME options, so I think remember it is not a good idea.

    2.3. KeyboardActions, maybe... But in terms of legibility I wouldn't do that...

    2.4. For FocusRequester makes sense to me remember it, otherwise you will attach a new FocusRequest to the components on each recomposition. Which might cause an unexpected behavior (focus jumping here and there)...

  3. Yes. But, as I mentioned above, this operation should not be done on the composable. It can be done on View Model or in other layers... Composable should received the list ready for use.

Upvotes: 2

Related Questions