1# @ohos.arkui.StateManagement (State Management) 2 3The state management module provides data storage, persistent data management, UIAbility data storage, and environment state and tools required by applications. 4 5>**NOTE** 6> 7>The initial APIs of this module are supported since API version 12. Newly added APIs will be marked with a superscript to indicate their earliest API version. 8 9 10The meanings of T and S in this topic are as follows: 11 12 13| Type | Description | 14| ---- | -------------------------------------- | 15| T | Class, number, boolean, string, and arrays of these types.| 16| S | number, boolean, string. | 17 18 19## Modules to Import 20 21```ts 22import { AppStorageV2,PersistenceV2,UIUtils} from '@kit.ArkUI'; 23``` 24 25## AppStorageV2 26 27For details about how to use AppStorageV2, see [AppStorageV2: Storing Application-wide UI State](../../quick-start/arkts-new-appstoragev2.md). 28 29**Atomic service API**: This API can be used in atomic services since API version 12. 30 31**System capability**: SystemCapability.ArkUI.ArkUI.Full 32 33### connect 34 35static connect\<T extends object\>( <br> 36 type: TypeConstructorWithArgs\<T\>, <br> 37 keyOrDefaultCreator?: string | StorageDefaultCreator\<T\>, <br> 38 defaultCreator?: StorageDefaultCreator\<T\> <br> 39): T | undefined 40 41Stores key-value pair data in the application memory. If the given key already exists in [AppStorageV2](../../quick-start/arkts-new-appstoragev2.md), it returns the corresponding value; otherwise, it constructs a default value using the constructor for obtaining the default value and returns it. 42 43**Atomic service API**: This API can be used in atomic services since API version 12. 44 45**System capability**: SystemCapability.ArkUI.ArkUI.Full 46 47**Parameters** 48 49| Name | Type | Mandatory| Description | 50| -------- | ------ | ---- | ---------------------- | 51| type | [TypeConstructorWithArgs\<T\>](#typeconstructorwithargst) | Yes | Type. If no key is specified, the name of the type is used as the key.| 52| keyOrDefaultCreator | string \| [StorageDefaultCreator\<T\>](#storagedefaultcreatort) | No | Key, or the constructor for obtaining the default value.| 53| defaultCreator | StorageDefaultCreator\<T\> | No | Constructor for obtaining the default value.| 54 55>**NOTE** 56> 57>1. The second parameter is used when no key is specified, and the third parameter is used otherwise. 58> 59>2. If the data has been stored in AppStorageV2, you can obtain the stored data without using the default constructor. If the data has not been stored, you must specify a default constructor; otherwise, an application exception will be thrown. 60> 61>3. Ensure that the data types match the key. Connecting different types of data to the same key will result in an application exception. 62> 63>4. You are advised to use meaningful values for the key, with a length not exceeding 255 characters. The behavior of using illegal characters or empty characters is undefined. 64 65**Return value** 66 67| Type | Description | 68| -------------------------------------- | ------------------------------------------------------------ | 69| T | Returns data if the creation or data acquisition from AppStorageV2 is successful; returns **undefined** otherwise.| 70 71**Example** 72 73```ts 74import { AppStorageV2 } from '@kit.ArkUI'; 75 76@ObservedV2 77class SampleClass { 78 @Trace p: number = 0; 79} 80 81// Store the key-value pair with the key SampleClass and the value as a new instance of SampleClass() in memory, and assign it to variable as1. 82const as1: SampleClass | undefined = AppStorageV2.connect(SampleClass, () => new SampleClass()); 83 84// Store the key-value pair with the key key_as2 and the value as a new instance of SampleClass() in memory, and assign it to variable as2. 85const as2: SampleClass = AppStorageV2.connect(SampleClass, 'key_as2', () => new SampleClass())!; 86 87// As the key SampleClass already exists in AppStorageV2, the value associated with the key is returned to variable as3. 88const as3: SampleClass = AppStorageV2.connect(SampleClass) as SampleClass; 89``` 90 91### remove 92 93static remove\<T\>(keyOrType: string | TypeConstructorWithArgs\<T\>): void 94 95Removes the specified key-value pair from [AppStorageV2](../../quick-start/arkts-new-appstoragev2.md). If the specified key does not exist in AppStorageV2, the removal will fail. 96 97**Atomic service API**: This API can be used in atomic services since API version 12. 98 99**System capability**: SystemCapability.ArkUI.ArkUI.Full 100 101**Parameters** 102 103| Name | Type | Mandatory| Description | 104| -------- | ------ | ---- | ---------------------- | 105| keyOrType | string \| TypeConstructorWithArgs\<T\> | Yes | Key to be removed. If a type is specified, the key to be deleted is the name of that type.| 106 107>**NOTE** 108> 109>Attempting to remove a key that does not exist in AppStorageV2 will result in a warning. 110 111 112**Example** 113 114<!--code_no_check--> 115```ts 116// Assuming that there is a key named key_as2 in AppStorageV2, the following will remove the corresponding key-value pair from AppStorageV2. 117AppStorageV2.remove('key_as2'); 118 119// Assuming that there is a key named SampleClass in AppStorageV2, the following will remove the corresponding key-value pair from AppStorageV2. 120AppStorageV2.remove(SampleClass); 121 122// Assuming there is no key named key_as1 in AppStorageV2, the following will result in a warning. 123AppStorageV2.remove('key_as1'); 124``` 125 126### keys 127 128static keys(): Array\<string\> 129 130Obtains all keys in [AppStorageV2](../../quick-start/arkts-new-appstoragev2.md). 131 132**Atomic service API**: This API can be used in atomic services since API version 12. 133 134**System capability**: SystemCapability.ArkUI.ArkUI.Full 135 136**Return value** 137 138| Type | Description | 139| -------------------------------------- | ------------------------------------------------------------ | 140| Array\<string\> | All keys stored in AppStorageV2.| 141 142>**NOTE** 143> 144>The order of the keys in the Array is not sequential and does not correspond to the order in which the keys were inserted into AppStorageV2. 145 146**Example** 147 148```ts 149// Assuming there are two keys (key_as1 and key_as2) in AppStorageV2, the following will return an array containing these keys and assign it to keys. 150const keys: Array<string> = AppStorageV2.keys(); 151``` 152 153 154 155## PersistenceV2 156 157Inherits from [AppStorageV2](#appstoragev2). For details, see [PersistenceV2: Persisting Application State](../../quick-start/arkts-new-persistencev2.md). 158 159**Atomic service API**: This API can be used in atomic services since API version 12. 160 161**System capability**: SystemCapability.ArkUI.ArkUI.Full 162 163### globalConnect<sup>18+</sup> 164 165static globalConnect\<T extends object\>(type: ConnectOptions\<T\>): T | undefined 166 167Stores key-value pair data on the application disk. If the given key already exists in [PersistenceV2](../../quick-start/arkts-new-persistencev2.md), the corresponding value is returned. Otherwise, a default value is constructed using the default value constructor and returned. If **globalConnect** is used for an @ObservedV2 decorated object, changes to the object's @Trace properties will trigger automatic refresh of the associated object, while changes to non-@Trace properties will not. If necessary, the **PersistenceV2.save** API can be called to store the data manually. 168 169**Atomic service API**: This API can be used in atomic services since API version 18. 170 171**System capability**: SystemCapability.ArkUI.ArkUI.Full 172 173| Name |Type |Mandatory | Description | 174| ------------- | ------------|-------------------|-------------------------- | 175| type |[ConnectOptions\<T\>](#connectoptions18) |Yes |**connect** parameter passed in. For details, see the description of **ConnectOptions**.| 176 177**Return value** 178 179|Type |Description | 180|----------|-----------------------------------| 181|T \| undefined |Returns the data if creation or acquisition is successful; otherwise, returns **undefined**. | 182 183> **NOTE** 184> 185> 1. The second parameter is used when no **key** is specified, and the third parameter is used otherwise (including when the second parameter is invalid). 186> 187> 2. If the data has been stored in PersistenceV2, you can obtain the stored data without using the default constructor. Otherwise, you must specify a default constructor to avoid application exceptions. 188> 189> 3. Ensure that the data types match the key. Matching different types of **globalConnect** data to the same key will result in an application exception. 190> 191> 4. You are advised to use meaningful values for keys. The values can contain letters, digits, and underscores (_) and a maximum of 255 characters. Using invalid characters or null characters will result in undefined behavior. 192> 193> 5. When matching the key with an [\@Observed](../../quick-start/arkts-observed-and-objectlink.md) object, specify the key or customize the **name** property. 194> 195> 6. The storage path for data is application-level. If different modules use the same key and the same encryption partition for **globalConnect**, only one copy of the data will be stored in the application. 196> 197> 7. If **globalConnect** is used with the same key but different encryption levels, the data will be stored with the encryption level of the first **globalConnect** call, and the data in **PersistenceV2** will also be stored with this encryption level. 198> 199> 8. Avoid using **connect** and **globalConnect** together, because they have different data copy paths. If they must be used together, make sure the keys are unique to avoid application crashes. 200> 201> 9. To enable EL5 encryption, configure the **ohos.permission.PROTECT_SCREEN_LOCK_DATA** field in the **module.json** file. For details, see [Declaring Permissions](../../security/AccessToken/declare-permissions.md). 202 203**Example** 204 205<!--code_no_check--> 206```ts 207import { PersistenceV2, Type, ConnectOptions } from '@kit.ArkUI'; 208import { contextConstant } from '@kit.AbilityKit'; 209 210@ObservedV2 211class SampleChild { 212 @Trace childId: number = 0; 213 groupId: number = 1; 214} 215 216@ObservedV2 217export class Sample { 218 // For complex objects, use the @Type decorator to ensure successful serialization. 219 @Type(SampleChild) 220 @Trace father: SampleChild = new SampleChild(); 221} 222 223// If no key is provided, the type name is used as the key. If the encryption level is not specified, the default EL2 level is used. 224@Local p: Sample = PersistenceV2.globalConnect({type: Sample, defaultCreator:() => new Sample()})!; 225 226// Use the key 'global1' with an encryption level of EL1 for connection. 227@Local p1: Sample = PersistenceV2.globalConnect({type: Sample, key:'global1', defaultCreator:() => new Sample(), areaMode: contextConstant.AreaMode.EL1})!; 228 229// Use the key 'global2' with the constructor function for connection. If no encryption level is specified, the default EL2 level is used. 230@Local p2: Sample = PersistenceV2.globalConnect({type: Sample, key: 'global2', defaultCreator:() => new Sample()})!; 231 232// Use the key 'global3' with an explicit encryption level value (3 in this example) for connection. Note that values outside the valid range of 0-4 will cause application crashes. 233@Local p3: Sample = PersistenceV2.globalConnect({type: Sample, key:'global3', defaultCreator:() => new Sample(), areaMode: 3})!; 234 235``` 236 237### save 238 239static save\<T\>(keyOrType: string | TypeConstructorWithArgs\<T\>): void 240 241Persists the specified key-value pair data once. 242 243**Atomic service API**: This API can be used in atomic services since API version 12. 244 245**System capability**: SystemCapability.ArkUI.ArkUI.Full 246 247**Parameters** 248 249| Name | Type | Mandatory| Description | 250| -------- | ------ | ---- | ---------------------- | 251| keyOrType | string \| TypeConstructorWithArgs\<T\> | Yes | Key to be persisted. If a type is specified, the key for persistence is the name of the type.| 252 253>**NOTE** 254> 255>Since changes to non-[\@Trace](../../quick-start/arkts-new-observedV2-and-trace.md) decorated data do not automatically trigger persistence through [PersistenceV2](../../quick-start/arkts-new-persistencev2.md), you can call this API to manually persist the data for the corresponding key when needed. 256> 257>It is useless to manually persist the keys that are not in the **connect** state in the memory. 258 259**Example** 260 261<!--code_no_check--> 262 263```ts 264// Assuming there is a key named key_as2 in PersistenceV2, the following will persist the data for this key-value pair. 265PersistenceV2.save('key_as2'); 266 267// Assuming there is a key named SampleClass in PersistenceV2, the following will persist the data for this key-value pair. 268PersistenceV2.remove(SampleClass); 269 270// Assuming there is no key named key_as1 in PersistenceV2, this operation is meaningless. 271PersistenceV2.remove('key_as1'); 272``` 273 274### notifyOnError 275 276static notifyOnError(callback: PersistenceErrorCallback | undefined): void 277 278Called when persistence fails. 279 280**Atomic service API**: This API can be used in atomic services since API version 12. 281 282**System capability**: SystemCapability.ArkUI.ArkUI.Full 283 284**Parameters** 285 286| Name | Type | Mandatory| Description | 287| -------- | ------ | ---- | ---------------------- | 288| callback | PersistenceErrorCallback \| undefined | Yes | Callback invoked when persistence fails.| 289 290**Example** 291 292```ts 293// Called when persistence fails. 294PersistenceV2.notifyOnError((key: string, reason: string, msg: string) => { 295 console.error(`error key: ${key}, reason: ${reason}, message: ${msg}`); 296}); 297``` 298 299## ConnectOptions<sup>18+</sup> 300 301**Atomic service API**: This API can be used in atomic services since API version 18. 302 303**System capability**: SystemCapability.ArkUI.ArkUI.Full 304 305|Name |Type |Read-Only |Optional |Description | 306|--------|------------|------------|-----------|--------------| 307|type | TypeConstructorWithArgs\<T\> |No |No |Specified type. | 308|key | string |No |Yes |key used for connection. If it is not provided, the name of the type is used as the key. | 309|defaultCreator | StorageDefaultCreator\<T\> |No |Yes |Default constructor. It is recommended that this parameter be passed in. If **globalConnect** is called for the first time with a key and this parameter is not provided, an error will occur.| 310|areaMode | contextConstant.AreaMode |No |Yes |Encryption level, ranging from EL1 to EL5 (corresponding to the value from 0 to 4). For details, see [Obtaining and Modifying Encryption Levels](../../application-models/application-context-stage.md). If no value is passed in, the default EL2 level is used. Different encryption levels correspond to different storage paths. Values outside the valid range of 0-4 will cause the application to crash.| 311 312## UIUtils 313 314Provides APIs for handling data transformations related to state management. 315 316**Atomic service API**: This API can be used in atomic services since API version 12. 317 318**System capability**: SystemCapability.ArkUI.ArkUI.Full 319 320### getTarget 321 322static getTarget\<T extends object\>(source: T): T 323 324Obtains the original object from a proxy object wrapped by the state management framework. For details, see [getTarget API: Obtaining Original Objects](../../quick-start/arkts-new-getTarget.md). 325 326**Atomic service API**: This API can be used in atomic services since API version 12. 327 328**System capability**: SystemCapability.ArkUI.ArkUI.Full 329 330**Parameters** 331 332| Name| Type| Mandatory| Description | 333| ------ | ---- | ---- | ------------ | 334| source | T | Yes | Source object.| 335 336**Return value** 337 338| Type| Description | 339| ---- | ------------------------------------------------ | 340| T | Original object of the source after the proxy added by the state management framework is removed.| 341 342**Example** 343 344```ts 345import { UIUtils } from '@kit.ArkUI'; 346class NonObservedClass { 347 name: string = "Tom"; 348} 349let nonObservedClass: NonObservedClass = new NonObservedClass(); 350@Entry 351@Component 352struct Index { 353 @State someClass: NonObservedClass = nonObservedClass; 354 build() { 355 Column() { 356 Text(`this.someClass === nonObservedClass: ${this.someClass === nonObservedClass}`) // false 357 Text(`UIUtils.getTarget(this.someClass) === nonObservedClass: ${UIUtils.getTarget(this.someClass) === 358 nonObservedClass}`) // true 359 } 360 } 361} 362``` 363### makeObserved 364 365static makeObserved\<T extends object\>(source: T): T 366 367Converts ordinary unobservable data into observable data. For details, see [makeObserved API: Changing Unobservable Data to Observable Data](../../quick-start/arkts-new-makeObserved.md). 368 369**Atomic service API**: This API can be used in atomic services since API version 12. 370 371**System capability**: SystemCapability.ArkUI.ArkUI.Full 372 373**Parameters** 374 375| Name| Type| Mandatory| Description | 376| ------ | ---- | ---- | ------------ | 377| source | T | Yes | Source object. It supports classes not decorated by @Observed or @ObserveV2, objects returned by **JSON.parse**, and classes decorated by @Sendable.<br>Array, Map, Set, and Date types are supported.<br>**collection.Array**, **collection.Set**, and **collection.Map** are supported.<br>For details, see [makeObserved API: Changing Unobservable Data to Observable Data](../../quick-start/arkts-new-makeObserved.md).| 378 379**Return value** 380 381| Type| Description | 382| ---- | ------------------------------------------------ | 383| T | Observable data.| 384 385**Example** 386 387```ts 388import { UIUtils } from '@kit.ArkUI'; 389class NonObservedClass { 390 name: string = 'Tom'; 391} 392 393@Entry 394@ComponentV2 395struct Index { 396 observedClass: NonObservedClass = UIUtils.makeObserved(new NonObservedClass()); 397 nonObservedClass: NonObservedClass = new NonObservedClass(); 398 build() { 399 Column() { 400 Text(`observedClass: ${this.observedClass.name}`) 401 .onClick(() => { 402 this.observedClass.name = 'Jane'; // This will trigger a UI update. 403 }) 404 Text(`observedClass: ${this.nonObservedClass.name}`) 405 .onClick(() => { 406 this.nonObservedClass.name = 'Jane'; // This will not trigger a UI update. 407 }) 408 } 409 } 410} 411``` 412 413## StorageDefaultCreator\<T\> 414 415type StorageDefaultCreator\<T\> = () => T; 416 417Obtains the default constructor. 418 419**Atomic service API**: This API can be used in atomic services since API version 12. 420 421**System capability**: SystemCapability.ArkUI.ArkUI.Full 422 423**Return value** 424 425| Type| Description | 426| ---- | ------------------------------------------------ | 427| () => T | Default constructor.| 428 429**Example** 430 431```ts 432import { PersistenceV2 } from '@kit.ArkUI'; 433 434@ObservedV2 435class SampleClass { 436 @Trace id: number = 0; 437 count: number = 1; 438} 439 440@ObservedV2 441class FatherSampleClass { 442 @Trace sampleClass: SampleClass = new SampleClass(); 443} 444 445// Persist the key-value pair with the key SampleClass and the value as an instance of SampleClass(), and assign it to variable source. 446// StorageDefaultCreator refers to the function () => new FatherSampleClass(). 447const source: FatherSampleClass | undefined = PersistenceV2.connect(FatherSampleClass, () => new FatherSampleClass()); 448 449@Entry 450@Component 451struct SampleComp { 452 data: FatherSampleClass | undefined = source; 453 454 build() { 455 Column() { 456 Text(`${this.data?.sampleClass.id}`) 457 } 458 } 459} 460``` 461 462## TypeConstructorWithArgs\<T\> 463 464Represents a class constructor that accepts arbitrary arguments. 465 466**Atomic service API**: This API can be used in atomic services since API version 12. 467 468**System capability**: SystemCapability.ArkUI.ArkUI.Full 469 470### new 471 472new(...args: any): T; 473 474**Atomic service API**: This API can be used in atomic services since API version 12. 475 476**System capability**: SystemCapability.ArkUI.ArkUI.Full 477 478**Parameters** 479 480| Name| Type| Mandatory| Description | 481| ------ | ---- | ---- | ------------ | 482| ...args | any | Yes | Function arguments. | 483 484**Return value** 485 486| Type| Description | 487| ---- | ------------------------------------------------ | 488| T | Instance of the T type.| 489 490**Example** 491 492```ts 493import { PersistenceV2 } from '@kit.ArkUI'; 494 495@ObservedV2 496 // TypeConstructorWithArgs refers to the SampleClass constructor. 497class SampleClass { 498 @Trace id: number = 0; 499 count: number = 1; 500} 501 502@ObservedV2 503class FatherSampleClass { 504 @Trace sampleClass: SampleClass = new SampleClass(); 505} 506 507// Persist the key-value pair with the key SampleClass and the value as an instance of SampleClass(), and assign it to variable source. 508const source: FatherSampleClass | undefined = PersistenceV2.connect(FatherSampleClass, () => new FatherSampleClass()); 509 510@Entry 511@Component 512struct SampleComp { 513 data: FatherSampleClass | undefined = source; 514 515 build() { 516 Column() { 517 Text(`${this.data?.sampleClass.id}`) 518 } 519 } 520} 521``` 522 523## PersistenceErrorCallback 524 525type PersistenceErrorCallback = (key: string, reason: 'quota' | 'serialization' | 'unknown', message: string) => void; 526 527Represents the callback invoked when persistence fails. 528 529**Atomic service API**: This API can be used in atomic services since API version 12. 530 531**System capability**: SystemCapability.ArkUI.ArkUI.Full 532 533**Parameters** 534 535| Name| Type| Mandatory| Description | 536| ------ | ---- | ---- | ------------ | 537| key | string | Yes | Key associated with the error. | 538|reason| 'quota' \| 'serialization' \| 'unknown' | Yes | Type of the error. | 539| message | string | Yes | Additional information about the error. | 540 541**Example** 542 543```ts 544import { PersistenceV2, Type } from '@kit.ArkUI'; 545 546@ObservedV2 547class SampleChild { 548 @Trace id: number = 0; 549 count: number = 10; 550} 551 552@ObservedV2 553export class Sample { 554 // For complex objects, use the @Type decorator to ensure successful serialization. 555 @Type(SampleChild) 556 @Trace sampleChild: SampleChild = new SampleChild(); 557} 558 559// Callback used to receive persistence errors. 560// PersistenceErrorCallback refers to (key: string, reason: string, msg: string) => {console.error(`error key: ${key}, reason: ${reason}, message: ${msg}`);}. 561PersistenceV2.notifyOnError((key: string, reason: string, msg: string) => { 562 console.error(`error key: ${key}, reason: ${reason}, message: ${msg}`); 563}); 564 565@Entry 566@ComponentV2 567struct Index { 568 // Create a key-value pair with the key Sample in PersistenceV2 (if the key exists, the data in PersistenceV2 is returned) and associate it with data. 569 // Add @Local to decorate the data property that needs to change the connected object. (Changing the connected object is not recommended.) 570 @Local data: Sample = PersistenceV2.connect(Sample, () => new Sample())!; 571 pageStack: NavPathStack = new NavPathStack(); 572 573 build() { 574 Text(`Index add 1 to data.id: ${this.data.sampleChild.id}`) 575 .fontSize(30) 576 .onClick(() => { 577 this.data.sampleChild.id++; 578 }) 579 } 580} 581``` 582 583## TypeConstructor\<T\> 584 585Class constructor. 586 587**Atomic service API**: This API can be used in atomic services since API version 12. 588 589**System capability**: SystemCapability.ArkUI.ArkUI.Full 590 591### new 592 593new(): T; 594 595**Return value** 596 597| Type| Description | 598| ---- | ------------------------------------------------ | 599| T | Instance of the T type.| 600 601**Atomic service API**: This API can be used in atomic services since API version 12. 602 603**System capability**: SystemCapability.ArkUI.ArkUI.Full 604 605**Example** 606 607```ts 608import { PersistenceV2, Type } from '@kit.ArkUI'; 609 610@ObservedV2 611class SampleChild { 612 @Trace id: number = 0; 613 count: number = 10; 614} 615 616@ObservedV2 617export class Sample { 618 // For complex objects, use the @Type decorator to ensure successful serialization. 619 // TypeConstructor refers to SampleChild. 620 @Type(SampleChild) 621 @Trace sampleChild: SampleChild = new SampleChild(); 622} 623 624@Entry 625@ComponentV2 626struct Index { 627 data: Sample = PersistenceV2.connect(Sample, () => new Sample())!; 628 629 build() { 630 Column() { 631 Text(`Index add 1 to data.id: ${this.data.sampleChild.id}`) 632 .fontSize(30) 633 .onClick(() => { 634 this.data.sampleChild.id++; 635 }) 636 } 637 } 638} 639``` 640 641## TypeDecorator 642 643type TypeDecorator = \<T\>(type: TypeConstructor\<T\>) => PropertyDecorator; 644 645Property decorator. 646 647**Atomic service API**: This API can be used in atomic services since API version 12. 648 649**System capability**: SystemCapability.ArkUI.ArkUI.Full 650 651**Parameters** 652 653| Name| Type| Mandatory| Description | 654| ------ | ---- | ---- | ------------ | 655| type | [TypeConstructor\<T\>](#typeconstructort) | Yes | Type of the class property decorated. | 656 657**Return value** 658 659| Type| Description | 660| ---- | ------------------------------------------------ | 661| PropertyDecorator | Property decorator.| 662 663**Example** 664 665```ts 666import { PersistenceV2, Type } from '@kit.ArkUI'; 667 668@ObservedV2 669class SampleChild { 670 @Trace id: number = 0; 671 count: number = 10; 672} 673 674@ObservedV2 675export class Sample { 676 // For complex objects, use the @Type decorator to ensure successful serialization. 677 // TypeDecorator refers to @Type. 678 @Type(SampleChild) 679 @Trace sampleChild: SampleChild = new SampleChild(); 680} 681 682@Entry 683@ComponentV2 684struct Index { 685 data: Sample = PersistenceV2.connect(Sample, () => new Sample())!; 686 687 build() { 688 Column() { 689 Text(`Index add 1 to data.id: ${this.data.sampleChild.id}`) 690 .fontSize(30) 691 .onClick(() => { 692 this.data.sampleChild.id++; 693 }) 694 } 695 } 696} 697``` 698