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等

 评论