ITmob-Ly
发布于 2024-05-23 / 170 阅读
0

理解 Jetpack Compose 中的Stateful & Stateless(有状态和无状态)

本文简单介绍下对 Jetpack Compose 中的有状态和无状态的理解。

参考:

https://developer.android.com/jetpack/compose/state

Stateful 有状态

有状态是指可组合项自己可以保持和修改自己的状态。

比如下面的代码:

@Composable
fun HelloContent() {
   Column(modifier = Modifier.padding(16.dp)) {
       var name by remember { mutableStateOf("https://itmob.cn") }
       if (name.isNotEmpty()) {
           Text(
               text = "Hello, $name!",
               modifier = Modifier.padding(bottom = 8.dp),
               style = MaterialTheme.typography.h5
           )
       }
       OutlinedTextField(
           value = name,
           onValueChange = { name = it },
           label = { Text("Name") }
       )
   }
}

这里的 Greeting 就是有状态的,因为它会在内部保持和修改自己的 name 状态。

调用方不需要控制状态,并且不必自行管理状态便可使用状态的情况下,“有状态”会非常有用。但是,具有内部状态的可组合项往往不易重复使用,也更难测试。

Stateless 无状态

无状态可组合项是指不保持任何状态的可组合项。实现无状态的一种简单方法是使用 状态提升 (将状态移至可组合项的调用方)。

@Composable
fun HelloScreen() {
    var name by rememberSaveable { mutableStateOf("https://itmob.cn") }

    HelloContent(name = name, onNameChange = { name = it })
}

@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "Hello, $name",
            modifier = Modifier.padding(bottom = 8.dp),
            style = MaterialTheme.typography.h5
        )
        OutlinedTextField(
            value = name,
            onValueChange = onNameChange,
            label = { Text("Name") }
        )
    }
}

上例中 HelloContent 是无状态的可组合项,因为它不保持任何的状态。相反,它只接收来自调用者的状态,这就是 “状态升级” 的用法。

开发可重用的组件时通常希望公开相同组合的有状态和无状态版本。有状态版本对于不关心状态的调用者很方便,而无状态版本对于需要控制或升级状态的调用者来说是必要的。