@Track
@Track概述
- @Track是class对象的属性装饰器。当一个class对象是状态变量时(也就是使用@State修饰时),@Track装饰的属性发生变化,只会触发该属性关联的UI更新;而未被标记的属性不能在UI中使用(这句话的意思是在一个class中,如果有@Track的话,只有@Track修饰的变量可以在UI中使用,别的普通属性不能在UI中使用,详见下文使用条件章节)。
- 注意当class对象中没有一个属性被标记@Track,行为与原先保持不变
使用案例
如下代码:
java
class LogTrack {
@Track str1: string;
@Track str2: string;
constructor(str1: string) {
this.str1 = str1;
this.str2 = 'World';
}
}
class LogNotTrack {
str1: string;
str2: string;
constructor(str1: string) {
this.str1 = str1;
this.str2 = '世界';
}
}
@Entry
@Component
struct AddLog {
@State logTrack: LogTrack = new LogTrack('Hello');
@State logNotTrack: LogNotTrack = new LogNotTrack('你好');
isRender(index: number) {
console.log(`Text ${index} is rendered`);
return 50;
}
build() {
Row() {
Column() {
Text(this.logTrack.str1) // UINode1
.fontSize(this.isRender(1))
.fontWeight(FontWeight.Bold)
Text(this.logTrack.str2) // UINode2
.fontSize(this.isRender(2))
.fontWeight(FontWeight.Bold)
Button('change logTrack.str1')
.onClick(() => {
this.logTrack.str1 = 'Bye';
}).backgroundColor(Color.Red)
Text(this.logNotTrack.str1) // UINode3
.fontSize(this.isRender(3))
.fontWeight(FontWeight.Bold)
Text(this.logNotTrack.str2) // UINode4
.fontSize(this.isRender(4))
.fontWeight(FontWeight.Bold)
Button('change logNotTrack.str1')
.onClick(() => {
this.logNotTrack.str1 = '再见';
})
}
.width('100%')
}
.height('100%')
}
}
- 初始化运行效果:
- 当点击红色按钮时,类
LogTrack
中的属性均被@Track
装饰器装饰,此时UINode1
刷新,UINode2
不刷新,只有一条日志输出,避免了冗余刷新。
- 当点击蓝色按钮时,类
LogNotTrack
中的属性均未被@Track装饰器装饰,此时UINode3、UINode4均会刷新,有两条日志输出,存在冗余刷新。
使用条件
- 不能在UI中使用非@Track装饰的属性,包括不能绑定在组件上、不能用于初始化子组件,错误的使用将导致
JSCrash
;可以在非UI中使用非@Track装饰的属性,如事件回调函数中、生命周期函数中等。
第一句是什么意思呢?比如我们将LogTrack
的str2的属性@Track
去掉的话,如图
再次运行,app会崩溃,报如下错误:意思是str2没有使用@Track标签装饰,不能在UI中使用
java
xxx.ee E [nodict]Error type:Error
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict]Error name:Error
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict]Error message:Illegal usage of not @Track'ed property 'str2' on UI!
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict]Stacktrace:
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict]SourceMap is not initialized yet
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict] at onOptimisedObjectPropertyRead (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:4039:4039)
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict] at get (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:2042:2042)
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict] at anonymous (entry/src/main/ets/pages/tztZFHeadPage.ets:86:25)
- 建议开发者不要混用包含@Track的class对象和不包含@Track的class对象,如联合类型中、类继承中等。
参考资料:
@Track装饰器:class对象属性级更新