A quick dive into how state management works internally in Compose
var text by remember { mutableStateOf("") }
@Composable
fun SampleScreen() {
var a = 0
Button(onClick = { a++ }) {
Text(text = "$a")
}
}
// modifying the local variable inside a compose function wouldn't cause
// update to the UI since view (Text) is not aware of the update
@Composable
fun SampleScreen2() {
var a by mutableStateOf(0)
Button(onClick = { a++ }) {
Text(text = "$a")
}
}
/*
* By using a state, the UI would be recomposed when the state value changed
*/
mutableStateOf()
functionfun <T> mutableStateOf( value: T, policy: SnapshotMutationPolicy<T> =
structuralEqualityPolicy() ): MutableState<T> = createSnapshotMutableState(value, policy)
@Composable
fun SampleScreen3() {
Column {
var a by mutableStateOf(0)
Text(text = "$a")
Button(onClick = { a++ }) {
Text(text = "$a")
}
}
}
/*
* If we run this code, you would see that a is always 0, why?
*/
@Composable
fun SampleScreen4() {
Column {
// Use remember to cache the State in the composer
var a by remember { mutableStateOf(0) }
Text(count = a)
Button(onClick = { a++ }) {
Text(text = "$a")
}
}
}
remember()
function@Composable
inline fun <T> remember(calculation: @DisallowComposableCalls () -> T): T =
currentComposer.cache(false, calculation)
// invalid = false imply that previous value is/becomes invalid
@ComposeCompilerApi
inline fun <T> Composer.cache(invalid: Boolean, block: () -> T): T {
@Suppress("UNCHECKED_CAST")
return rememberedValue().let {
if (invalid || it === Composer.Empty) {
val value = block()
updateRememberedValue(value)
value
} else it
} as T
}