Why does mutableStateOf without remember work sometimes?

It’s a feature of Compose about scoping and smart recomposition. You can check my detailed answer here.

What really makes your whole Composable to recompose is Column having inline keyword.

@Composable
inline fun Column(
    modifier: Modifier = Modifier,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    content: @Composable ColumnScope.() -> Unit
) {
    val measurePolicy = columnMeasurePolicy(verticalArrangement, horizontalAlignment)
    Layout(
        content = { ColumnScopeInstance.content() },
        measurePolicy = measurePolicy,
        modifier = modifier
    )
}

Let’s say you have a Composable sets background color initially at composition and changes at each recomposition which creates its own scope. Lambda without inline is considered a scope.

@Composable
fun RandomColorColumn(content: @Composable () -> Unit) {

    Column(
        modifier = Modifier
            .padding(4.dp)
            .shadow(1.dp, shape = CutCornerShape(topEnd = 8.dp))
            .background(getRandomColor())
            .padding(4.dp)
    ) {
        content()
    }
}

With

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

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

And one with Column

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

    Column(modifier = Modifier.background(getRandomColor())) {
        TextField(text, onValueChange = { text = it })
        Button(onClick = {
            text = "Hello, Desktop!"
        }) {
            Text(text)
        }
    }
}

Random color function

fun getRandomColor() =  Color(
    red = Random.nextInt(256),
    green = Random.nextInt(256),
    blue = Random.nextInt(256),
    alpha = 255
)

You will see that Column background color will change every time you change text but not with App2()

enter image description here

Leave a Comment