LFK mobile DevPods

Presenting the latest mobile development and life of Engineers in LINE Fukuoka, Japan

  • Po
Published: 2022/02/16 119 views

About this episode

A quick dive into how state management works internally in Compose

About state declaration in Jetpack Compose

  • About the speaker
  • What is Jetpack Compose
  • We often do something like this in Jetpack Compose, but why?
var text by remember { mutableStateOf("") } 	
  • Reference of this episode could also be found here

Declaring state in different ways

  • As a normal local variable
@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	
  • As a SnapShotState
@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
*/
  • the mutableStateOf() function
fun <T> mutableStateOf( value: T, policy: SnapshotMutationPolicy<T> = 
    structuralEqualityPolicy() ): MutableState<T> = createSnapshotMutableState(value, policy)

To Remember the state

  • Let’s break our previous example
@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?
*/
  • To remember our state
@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")
        }
    }
}
  • the 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
}

Ending

10秒前へ 10秒次へ