一、状态绑定的注意事项:
- 减少不必要的参数层层传递
当按照上述优先级选择装饰器时,由于@State+@Prop、@State+@Link、@State+@Observed+@ObjectLink三种方案的实现方式是逐级向下传递状态,当共享状态的组件间层级相差较大时,会出现状态层层传递的现象。对于状态传递过程中途经的全部组件,都需要增加入参接收该状态再将状态传递给子组件。对于没有使用该状态的中间组件而言,这是“额外的消耗”,不利于代码的维护和拓展。尤其是当业务体系庞大时,需求变更容易出现“牵一发而动全身”的问题。
- 最小化状态共享范围
在没有强烈的业务需求下,尽可能按照状态需要共享的最小范围选择合适的装饰器。应用开发过程中,按照组件颗粒度,状态一般分为组件内独享的状态和组件间需要共享的状态。
- 集中化状态修改逻辑
在使用@Link装饰器时,开发者可以直接在@Link装饰器接收状态的组件内部修改状态。当多个子组件修改状态的逻辑基本相同时,建议将状态的修改集中到单个函数中,以提升逻辑的可复用性、代码的可维护性和可测试性。
二、不同的组合方案
-
@State+@Prop组合方案:
- @Prop装饰器支持接收Object、class、string、number、boolean、enum类型,以及这些类型的数组。
- @Prop装饰的变量是对父组件传入状态值的深拷贝,当@Prop装饰器装饰的变量为复杂Object、class或其类型数组时,会增加状态创建时间以及占用大量内存。
- @Prop装饰的变量和父组件是单向绑定的关系。当父组件数据源发生变化时,接收该数据源的@Prop所在组件的实例会重新渲染。 当该组件内被@Prop装饰的变量被修改时,父组件数据源不会变化,父组件实例也不会重新渲染。
-
@State+@Link组合方案:
- @Link装饰器支持接收Object、class、string、number、boolean、enum类型,以及这些类型的数组。
- @Link装饰器修饰的变量是对父组件传入状态的引用的拷贝,两者指向同一个地址。当状态是简单数据类型或简单Object类型时,@Link和@Prop在状态创建时间和内存的占用方面区别不大。当状态为复杂的Object、class或其类型数组时,@Link相较@Prop能明显减少状态创建时间和内存的占用。
- @Link装饰器的变量和父组件是双向绑定的关系。当父组件数据源发生变化时,接收该数据源的@Link所在组件的实例会重新渲染。 当该组件内被@Link装饰的变量被修改时,父组件数据源会同步修改,父组件实例也会重新渲染。
-
@State+@Observed+@ObjectLink组合方案:
- @ObjectLink只支持接收被@Observed装饰的class实例及继承Date或者Array的class实例。
- @ObjectLink装饰的变量是只读的,不支持对状态重新赋值。
- @ObjectLink必须配合@Observed使用,它的设计是为了解决对嵌套类对象属性变化的监听,如需要观察对象数组中单个数据项的属性值变化,或嵌套对象的对象类型属性的子属性变化。
结合三个方案的特性,在选择时有如下建议:
- 需要观察嵌套类对象的深层属性变化的场景,选择@State+@Observed+@ObjectLink。
- 状态是复杂对象、类或其类型数组的场景,选择@State+@Link。
- 状态是简单数据类型时,使用@State+@Link和@State+@Prop均可。在功能层面上,依据@Prop单向绑定的特性,@State+@Prop适合用于非实时修改的场景,如编辑电话薄联系人信息时,展示编辑界面的子组件信息的修改要求不实时同步回父组件,需要等到编辑完成后点击“确认”按钮时才会以事件驱动的方式修改父组件的状态。依据@Link双向绑定的特性,@State+@Link适合用于实时修改的场景,如组件嵌套时的滚动条同步。