状态管理机制
如果希望构建一个动态的、有交互的界面,就需要引入“状态”的概念。
在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染
,在ArkUI中统称为状态管理机制
。
基本概念
状态变量
:被状态装饰器装饰的变量,状态变量值的改变会引起UI的渲染更新。
常规变量
:没有被状态装饰器装饰的变量,通常应用于辅助计算。它的改变永远不会引起UI的刷新。
数据源/同步源
:状态变量的原始来源,可以同步给不同的状态数据。通常意义为父组件传给子组件的数据。
命名参数机制
:父组件通过指定参数传递给子组件的状态变量,为父子传递同步参数的主要手段。示例:CompA({ aProp: this.aProp })。
从父组件初始化
:父组件使用命名参数机制,将指定参数传递给子组件。子组件初始化的默认值在有父组件传值的情况下,会被覆盖。
初始化子组件
:父组件中状态变量可以传递给子组件,初始化子组件对应的状态变量。
本地初始化
:在变量声明的时候赋值,作为变量的默认值。
@State装饰器:组件内状态
@State装饰的变量拥有其所属组件的状态,可以作为其子组件单向和双向同步的数据源。当其数值改变时,会引起相关组件的渲染刷新。
@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就可以触发其直接绑定UI组件的刷新。当状态改变时,UI会发生对应的渲染改变。
在状态变量相关装饰器中,@State是最基础的,使变量拥有状态属性的装饰器,它也是大部分状态变量的数据源。
@State装饰的变量,与声明式范式中的其他被装饰变量一样,是私有的,只能从组件内部访问,在声明时必须指定其类型和本地初始化。初始化也可选择使用命名参数机制从父组件完成初始化。
@State装饰的变量拥有以下特点:
@State装饰的变量与子组件中的@Prop装饰变量之间建立单向数据同步, 与@Link、@ObjectLink装饰变量之间建立双向数据同步。
@State装饰的变量生命周期与其所属自定义组件
的生命周期相同。
观察变化和行为表现
并不是状态变量的所有更改都会引起UI的刷新,只有可以被框架观察到的修改才会引起UI刷新。
- 当装饰的数据类型为boolean、string、number类型时,可以观察到数值的变化。
- 当装饰的数据类型为class或者Object时,可以观察到自身的赋值的变化,和其属性赋值的变化,即Object.keys(observedObject)返回的所有属性。嵌套属性的赋值观察不到。
- 当装饰的对象是array时,可以观察到数组本身的赋值和添加、删除、更新数组的变化。数组项中属性的赋值观察不到。
- 当装饰的对象是Date时,可以观察到Date整体的赋值,同时可通过调用Date的接口setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime, setUTCFullYear, setUTCMonth, setUTCDate, setUTCHours, setUTCMinutes, setUTCSeconds, setUTCMilliseconds 更新Date的属性。
- 当装饰的变量是Map时,可以观察到Map整体的赋值,同时可通过调用Map的接口set, clear, delete 更新Map的值。详见装饰Map类型变量。
- 当装饰的变量是Set时,可以观察到Set整体的赋值,同时可通过调用Set的接口add, clear, delete 更新Set的值。详见装饰Set类型变量。
框架行为
当状态变量被改变时,查询依赖该状态变量的组件;
执行依赖该状态变量的组件的更新方法,组件更新渲染;
和该状态变量不相关的组件或者UI描述不会发生重新渲染,从而实现页面渲染的按需更新。