1

I have a remembered mutable state of type String (message) in one composable (MainView). If I modify the string and navigate to another composable (NextView), upon popping back, the modification is not remembered. If I use rememberSaveable instead, the modification is remembered. Is this the expected behavior of remember {}? If so, is navigation to another composable and back considered a configuration change?

I'm using Android 12 (API Level 31), Kotlin 1.5.31, compose version 1.1.0-alpha06, navigation-compose 2.4.0-alpha10, lifecycle-runtime-ktx 2.4.0-rc01, activity-compose 1.4.0-rc01.

Here's my code:

@Composable fun MainView(navController: NavController) { var message by remember { mutableStateOf("Message") } // modification remembered if rememberSaveable used instead Column { TextField( value = message, onValueChange = { message = it } ) Button(onClick = { navController.navigate("NextView") }) { Text(text = "MainView") } } } @Composable fun NextView(navController: NavController) { Button(onClick = { navController.popBackStack() }) { Text(text = "NextView") } } 

(I'd be happy to share my other dependency and system info and the MainActivity where I set up NavHost with these two views if helpful.)

1 Answer 1

1

Navigation is not considered a configuration change. Changes to your device such as its orientation, changing the default system language, wifi switching on/off are configuration changes. In most cases, a configuration change will result in your activity being destroyed. If your activity gets destroyed, anything that uses just remember gets lost. But if you use rememberSaveable, the state will be restored when the activity gets restarted.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer. Such being the case, why do I need to use rememberSaveable instead of simply remember in my example code for message to be remembered across navigation to another composable and back?
Compose maintains the state of your composable when it recomposes it. If you navigate to a different composable, the previous composable is destroyed - along with the state kept by "remember". If you want to retain that state, rememberSaveable will preserve it when you navigate back. When you are navigating to and from screens, you are not recomposing but composing from a fresh start.
Thanks for the clarification! I also noticed that rememberSaveable preserves state only if its composable is still on the navigation stack. Once its composable is popped off the stack, none of its states will be further retained.
To be honest, I rarely use rememberSaveable due to issues like the kind you mentioned. I wrote Jetmagic to better handle the state of UIs and their viewmodels even when the activity is destroyed and restarted. Give it shot: github.com/JohannBlake/Jetmagic
The thing is that both LaunchedEffect and DisposableEffect are also run on navigation away to another composable and back. Same behavior as on orientation change. For all practical purposes, maybe it's easiest to treat compose navigation as configuration change . . . .

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.