Why doesn’t `Modifier.testTag("42")` cause a recom...
# compose
a
Why doesn’t
Modifier.testTag("42")
cause a recomposition of the function it’s passed to, but
Modifier.testTag(functionThatReturns42())
does?
This prints “(Re)composing MyText” twice:
Copy code
@Composable
private fun MyText(
    modifier: Modifier
) {
    println("(Re)composing MyText")
    Text("Hello", modifier = modifier)
}

private fun makeTestTag(): String {
    return "42"
}


fun main() = singleWindowApplication {
    var number by remember { mutableStateOf(1) }
    Column {
        Text("$number")
        MyText(
            Modifier.testTag(makeTestTag())
        )
    }
    LaunchedEffect(Unit){
        delay(2000)
        number += 1
    }
}
But if I replace
makeTestTag()
with
"42"
it prints it only once.
wow, it prints it twice even if
makeTestTag
is inline!
That has got to be a bug in the compose compiler, no?
a
Maybe comparison is
===
? "42" is constant; function is evaluated every time
number
changes, thus returns a new string every time.
even if
makeTestTag
is inline
hmm no idea
a
“42” is an interned constant regardless of where it appears. At least that’s how it is in Java.
But regardless, I don’t think it should compare references.
s
"42" is inferred to be static (const), and modifier testTag has stable annotation on it, so if expression you pass there is constant, we infer it as never changing in the second case, modifier is not inferred as static because of the function call, so new instance of modifier causes recomposition. to fix this, consider hoisting modifier to the scope that does not recompose, or you can technically try applying @stable to the function that returns const value
a
Ah, I forgot functions could also be marked as
@Stable
. Yeah, that solves it.