Home > Blockchain >  Why does mutableStateOf without remember work sometimes?
Why does mutableStateOf without remember work sometimes?

Time:02-11

I've been playing with Jetpack Compose Desktop. I noticed something I really don't understand:

import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application

@Composable
@Preview
fun App() {
    var text by mutableStateOf("Hello, World!")

    MaterialTheme {
        TextField(text, onValueChange = { text = it })
        Button(onClick = {
            text = "Hello, Desktop!"
        }) {
            Text(text)
        }
    }
}

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        App()
    }
}

Why am I able to change the text in the TextField? I thought, that on every recompose the mutable state get reinstanciated with the initial Value: so the Text should not be able to change

import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application

@Composable
@Preview
fun App() {
    var text by mutableStateOf("Hello, World!")

    Column {
        TextField(text, onValueChange = { text = it })
        Button(onClick = {
            text = "Hello, Desktop!"
        }) {
            Text(text)
        }
    }
}

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        App()
    }
}

However, if you replace the MaterialTheme with an Column it suddendly works as expected and you aren't able to change the text in the TextField.

Why is that? Is that a bug or a feature?

CodePudding user response:

It's a feature of Compose about scoping and smart recomposition. You can check my detailed answer enter image description here

CodePudding user response:

I thought, that on every recompose the mutable state get reinstanciated with the initial Value: so the Text should not be able to change

The point of having a state when recomposing is to prevent a variable from being re-initialized. The initial state is used only once when the first composition occurs and isn't used again when further recompositions occur. If however the composable is removed from the UI tree and then reinstated later on, the state of the variable will be destroyed and re-initialized as this is not really a recomposition but a composition (as if it were happening for the first time).

  • Related