Stateless
- 所谓Compose的无状态,表示的是不关心控件本身的属性。
- 如:TextView的setText()/getText()这些都是控件本身的属性。因为Compose的设计我们不再去关心这些属性的控制。
- 正如我们无法获取Text("String")中的“String”值。
- 这就是Stateless特征。
部分Stateless
- 事实上Compose并不是全量无状态的实现。
- 正如Text("string"),我们无法获取其中的“string”字符串了。
- 但是事实上我们在程序研发过程中,Text()不会永远写死一个文案。这个文案时频繁变化的。
- 因此,Compose的设计只是让我们局部地不再关心某一些属性,并且通过抽离的方式,实现我们在外部只控制我们关心属性。
setContent{
val name by remember { mutableStateOf("value") }
Text(name)
}//name就是一个我们抽离出来关心的属性。我们只关心这个value的变更,而不是关心value对应的Text()的变更。
##无状态和有状态(状态提升)
无状态
- 比如下面的代码:
@Composable
fun CustomView(){
Text("Rock'N'Roll")
}
- 因为我们提供的是一个自定义封装的View,View内部显示了一个“Rock'N'Roll”的Text。其内部数据是我们无法变更的。因此这个数据就是CustomView的内部状态
- 因为这个状态是ComposeView的内部状态,所以它就是一个有状态的组件
###有状态
- 相反,如果我们把“Rock'N'Roll”提取出来,允许外部自定义
@Composable
fun CustomView(txt:String){
Text(txt)
}
- 通过这样的State Hoisting(状态提升)的方式,就能够将一个无状态的组件,变成一个有组件了。
单向数据流
TextField
- 如下代码:
setContent{
var value by remember { mutableStateOf("") }
TextField(value,{
value=it//TextField必须在onValueChange的回调中,绑定数据的变更,才能有效的更新编辑框里的数据
})
}
- 上述方式的代码编写,总感觉别扭。但这是Compose设计的初衷。主要原因是遵循:所有的UI变更,都应该交给开发者来决定是否需要执行。
- 如果不是这样做的话,就违背了单一数据来源的原则。TexField在编辑的时候,数据变更来源可能会有多个,就让Ui变更变得不可控了。
- 从Compose的设计角度来看,单向数据流的流向会是一个回环:数据往下,事件往上的单向数据流环。
- 如:CheckBox等