Is there a problem in passing a MutableState (reme...
# compose-android
d
Is there a problem in passing a MutableState (remembered) to all the screens to set the state of the scaffold (topbar, bottom bar, etc...) holding them? It seems like when I navigate from a dialog to another composable that sets it, it just ignores what it was set to... apart from that all other screens seem to be able to set it. Maybe there's a better way?
z
I’m not quite sure what you mean, can you share some code snippets? In particular, what does “composable that sets it … ignores what it was set to” mean?
d
I have something like this:
Copy code
sealed interface MainScaffoldState {
    data object Full : MainScaffoldState

    @Immutable
    data class TitleOnly(
        val title: String,
        val dotMenu: List<DotMenuItem> = emptyList(),
    ) : MainScaffoldState

    data object Search : MainScaffoldState

    data object Manage : MainScaffoldState
}

@Composable
fun rememberMainScaffoldState() = remember {
    mutableStateOf<MainScaffoldState>(MainScaffoldState.Full)
}

    Scaffold(
//        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        snackbarHost = { SnackbarHost(hostState = snackbarState) },
        topBar = {
            when (val currState = mainScaffoldState.value) {
                is MainScaffoldState.Full ->
And then I pass down
mainScaffoldState
to my screens and set it there when needed
But at a certain point I navigated to a dialog and then back to a regular screen with navController and it stayed in the Full mode, instead of going to TitleOnly even though I set it to that in that composable, as if it was getting a new instance of that state and keeping the old one how it was.
But when I started using compose-destinations' DestinationsNavHost it started working for some reason... I'm wondering if this thing about passing down the mutable state to composables and changing it there is problematic for some reason?
Like:
Copy code
@Composable
fun HomeScreen(mainScaffoldState: MUtableState<MAinScaffoldState>) {
   mainScaffoledSTate.value = MAinScaffoldState.TitleOnly("...")
z
That’s a smell for a couple reasons: 1. 2 sources of truth for your state: the nav/composable that decides which composable to call, and the value of
mainScaffoldState
. Worse, these two sources of truth form a feedback loop, which is always gonna be error-prone and hard to reason about. 2. Backwards data flow: state should flow down, not up.
d
So what could be done instead? I find that being able to define the state of the scaffold at the screen level avoids coupling the scaffold to every screen in the app (sometimes becoming a very large number), and also a humounguous when statement in the scaffold for all the screens...