1# \@Track Decorator: Class Object Property-level Update 2 3 4\@Track is a decorator used to decorate properties of class objects. Any changes to the properties decorated by \@Track will trigger only updates to the UI associated with those properties. 5 6 7Before reading this topic, you are advised to read [\@State](./arkts-state.md) to have an understanding of the basic observation capabilities of state management. 8 9> **NOTE** 10> 11> This decorator is supported in ArkTS widgets since API version 11. 12 13 14## Overview 15 16\@Track enables property-level update for the class object. When a class object is a state variable, the change of the \@Track decorated property triggers only the update of the property associated UI. If the class uses the \@Track decorator, the properties that are not decorated by \@Track cannot be used in the UI. Otherwise, a runtime error is reported. 17 18 19## Decorator Description 20 21| \@Track Decorator | Description | 22| ------------------ | -------------------- | 23| Decorator parameters | None.| 24| Allowed variable types| Non-static properties of class objects.| 25 26 27 28## Observed Changes and Behavior 29 30When a class object is a state variable, any changes to its properties decorated by \@Track will trigger only updates to the UI associated with those properties. 31 32> **NOTE** 33> 34> When no property in the class object is decorated with \@Track, the behavior remains unchanged. \@Track is unable to observe changes of nested objects. 35 36Using the @Track decorator can avoid redundant updates. 37 38```ts 39class LogTrack { 40 @Track str1: string; 41 @Track str2: string; 42 43 constructor(str1: string) { 44 this.str1 = str1; 45 this.str2 = 'World'; 46 } 47} 48 49class LogNotTrack { 50 str1: string; 51 str2: string; 52 53 constructor(str1: string) { 54 this.str1 = str1; 55 this.str2 = 'World'; 56 } 57} 58 59@Entry 60@Component 61struct AddLog { 62 @State logTrack: LogTrack = new LogTrack('Hello'); 63 @State logNotTrack: LogNotTrack = new LogNotTrack('Hello'); 64 65 isRender(index: number) { 66 console.log(`Text ${index} is rendered`); 67 return 50; 68 } 69 70 build() { 71 Row() { 72 Column() { 73 Text(this.logTrack.str1) // Text1 74 .fontSize(this.isRender(1)) 75 .fontWeight(FontWeight.Bold) 76 Text(this.logTrack.str2) // Text2 77 .fontSize(this.isRender(2)) 78 .fontWeight(FontWeight.Bold) 79 Button('change logTrack.str1') 80 .onClick(() => { 81 this.logTrack.str1 = 'Bye'; 82 }) 83 Text(this.logNotTrack.str1) // Text3 84 .fontSize(this.isRender(3)) 85 .fontWeight(FontWeight.Bold) 86 Text(this.logNotTrack.str2) // Text4 87 .fontSize(this.isRender(4)) 88 .fontWeight(FontWeight.Bold) 89 Button('change logNotTrack.str1') 90 .onClick(() => { 91 this.logNotTrack.str1 = 'Goodbye'; 92 }) 93 } 94 .width('100%') 95 } 96 .height('100%') 97 } 98} 99``` 100 101In the preceding example: 102 1031. All properties in the **LogTrack** class are decorated by \@Track. After the **change logTrack.str1** button is clicked, **Text1** is updated, but **Text2** is not, as indicated by that only one log record is generated. 104 ```ts 105 Text 1 is rendered 106 ``` 107 1082. None of the properties in the **logNotTrack** class is decorated by \@Track. After the **change logTrack.str1** button is clicked, both **Text3** and **Text4** are updated, as indicated by that two log records are generated. Redundant updates occur. 109 ```ts 110 Text 3 is rendered 111 Text 4 is rendered 112 ``` 113 114## Constraints 115 116- If the \@Track decorator is used in a class, the non-\@Track decorated properties in the class cannot be used in the \@Component decorated UI. For example, these properties cannot be bound to components nor be used to initialize child components; otherwise, an error is reported during runtime. For details, see [Improperly Using Non-\@Track Decorated Properties Causes Errors](#improperly-using-non-track-decorated-properties-causes-errors). Non-\@Track decorated properties can be used in non-UI functions, such as event callback functions and lifecycle functions. 117 118- Since API version 18 and later, \@Track is used in the \@ComponentV2 decorated UI. In this case, an error is not reported during runtime, but the refresh is not responded. For details, see [Common Scenarios](./arkts-v1-v2-mixusage.md#observed-decorated-class). 119 120- Whenever possible, avoid any combination of class objects that contain \@Track and those that do not in, for example, union types and class inheritance. 121 122 123## Use Scenarios 124 125### \@Track and Custom Component Updates 126 127This example is used to clarify the processing steps of custom component updates and \@Track. The **log** object is a state variable decorated by \@State. Its **logInfo** property is decorated by \@Track, but other properties are not, and the values of these other properties are not updated through the UI. 128 129 130```ts 131class Log { 132 @Track logInfo: string; 133 owner: string; 134 id: number; 135 time: Date; 136 location: string; 137 reason: string; 138 139 constructor(logInfo: string) { 140 this.logInfo = logInfo; 141 this.owner = 'OH'; 142 this.id = 0; 143 this.time = new Date(); 144 this.location = 'CN'; 145 this.reason = 'NULL'; 146 } 147} 148 149@Entry 150@Component 151struct AddLog { 152 @State log: Log = new Log('origin info.'); 153 154 build() { 155 Row() { 156 Column() { 157 Text(this.log.logInfo) 158 .fontSize(50) 159 .fontWeight(FontWeight.Bold) 160 .onClick(() => { 161 // Properties that are not decorated by @Track can be used in click events. 162 console.log('owner: ' + this.log.owner + 163 ' id: ' + this.log.id + 164 ' time: ' + this.log.time + 165 ' location: ' + this.log.location + 166 ' reason: ' + this.log.reason); 167 this.log.time = new Date(); 168 this.log.id++; 169 170 this.log.logInfo += ' info.'; 171 }) 172 } 173 .width('100%') 174 } 175 .height('100%') 176 } 177} 178``` 179 180Processing steps: 181 1821. The click event **Text.onClick** of the **AddLog** custom component increases the value of **info**. 183 1842. In response to the change of the \@State decorated variable **log**, the \@Track decorated property **logInfo** is updated, and the **Text** component is re-rendered. 185 186## FAQs 187 188### Improperly Using Non-\@Track Decorated Properties Causes Errors 189 190If a non-\@Track decorated property is used in the UI, an error is reported during runtime. 191 192```ts 193class Person { 194 // id is decorated by @Track. 195 @Track id: number; 196 // age is not decorated by @Track. 197 age: number; 198 199 constructor(id: number, age: number) { 200 this.id = id; 201 this.age = age; 202 } 203} 204 205@Entry 206@Component 207struct Parent { 208 @State parent: Person = new Person(2, 30); 209 210 build() { 211 // Property that is not decorated by @Track cannot be used in the UI. Otherwise, an error is reported during runtime. 212 Text(`Parent id is: ${this.parent.id} and Parent age is: ${this.parent.age}`) 213 } 214} 215``` 216