Lodea
Lodea

Reputation: 189

Is it possible to remember the state of a composable function?

I am trying to remember the state of a variable of type @Composable ()->Unit, I get no compiler errors but the app crashes on launch.

Why does this happen and what is the best way to fix it?

Minimal reproducible example:

@Composable
fun App(isHappy: Boolean) {
    var page: @Composable ()->Unit by rememberSaveable { mutableStateOf({}) }

    val happy = @Composable {
        Text("I'm happy")
    }

    val sad = @Composable {
        Text("I'm sad")
        Text("and angry!")
    }

    page = if(isHappy) happy else sad

    page()
}


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            App(true)
        }
    }
}

Upvotes: 2

Views: 3405

Answers (1)

chuckj
chuckj

Reputation: 29515

A composable function can be "remembered" but it is not "savable" as it is not serializable because it can easily capture state that is not serializable. Trying to use it in a rememberSavable will cause a runtime exception.

Consider, instead, remembering the value used to calculate the composable function, not the resulting function. For example,

@Composable
fun App() {
    var isHappy by rememberSaveable { mutableStateOf(true) }

    val happy = @Composable {
        Text("I'm happy")
    }

    val sad = @Composable {
        Text("I'm sad")
        Text("and angry!")
    }

    val page = if (isHappy) happy else sad

    Column {
      page()
      Button({ isHappy = !isHappy }) {
        Text("Toggle happiness")
      }
    }
}


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            App()
        }
    }
}

Upvotes: 4

Related Questions