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### save 164 165static save\<T\>(keyOrType: string | TypeConstructorWithArgs\<T\>): void; 166 167Persists the specified key-value pair data once. 168 169**Atomic service API**: This API can be used in atomic services since API version 12. 170 171**System capability**: SystemCapability.ArkUI.ArkUI.Full 172 173**Parameters** 174 175| Name | Type | Mandatory| Description | 176| -------- | ------ | ---- | ---------------------- | 177| keyOrType | string \| TypeConstructorWithArgs\<T\> | Yes | Key to be persisted. If a type is specified, the key for persistence is the name of the type.| 178 179>**NOTE** 180> 181>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. 182> 183>It is useless to manually persist the keys that are not in the **connect** state in the memory. 184 185**Example** 186 187<!--code_no_check--> 188 189```ts 190// Assuming there is a key named key_as2 in PersistenceV2, the following will persist the data for this key-value pair. 191PersistenceV2.save('key_as2'); 192 193// Assuming there is a key named SampleClass in PersistenceV2, the following will persist the data for this key-value pair. 194PersistenceV2.remove(SampleClass); 195 196// Assuming there is no key named key_as1 in PersistenceV2, this operation is meaningless. 197PersistenceV2.remove('key_as1'); 198``` 199 200### notifyOnError 201 202static notifyOnError(callback: PersistenceErrorCallback | undefined): void; 203 204Called when persistence fails. 205 206**Atomic service API**: This API can be used in atomic services since API version 12. 207 208**System capability**: SystemCapability.ArkUI.ArkUI.Full 209 210**Parameters** 211 212| Name | Type | Mandatory| Description | 213| -------- | ------ | ---- | ---------------------- | 214| callback | PersistenceErrorCallback \| undefined | Yes | Callback invoked when persistence fails.| 215 216**Example** 217 218```ts 219// Called when persistence fails. 220PersistenceV2.notifyOnError((key: string, reason: string, msg: string) => { 221 console.error(`error key: ${key}, reason: ${reason}, message: ${msg}`); 222}); 223``` 224 225## UIUtils 226 227Provides APIs for handling data transformations related to state management. 228 229**Atomic service API**: This API can be used in atomic services since API version 12. 230 231**System capability**: SystemCapability.ArkUI.ArkUI.Full 232 233### getTarget 234 235static getTarget\<T extends object\>(source: T): T; 236 237Obtains 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). 238 239**Atomic service API**: This API can be used in atomic services since API version 12. 240 241**System capability**: SystemCapability.ArkUI.ArkUI.Full 242 243**Parameters** 244 245| Name| Type| Mandatory| Description | 246| ------ | ---- | ---- | ------------ | 247| source | T | Yes | Source object.| 248 249**Return value** 250 251| Type| Description | 252| ---- | ------------------------------------------------ | 253| T | Original object of the source after the proxy added by the state management framework is removed.| 254 255**Example** 256 257```ts 258import { UIUtils } from '@kit.ArkUI'; 259class NonObservedClass { 260 name: string = "Tom"; 261} 262let nonObservedClass: NonObservedClass = new NonObservedClass(); 263@Entry 264@Component 265struct Index { 266 @State someClass: NonObservedClass = nonObservedClass; 267 build() { 268 Column() { 269 Text(`this.someClass === nonObservedClass: ${this.someClass === nonObservedClass}`) // false 270 Text(`UIUtils.getTarget(this.someClass) === nonObservedClass: ${UIUtils.getTarget(this.someClass) === 271 nonObservedClass}`) // true 272 } 273 } 274} 275``` 276### makeObserved 277 278static makeObserved\<T extends object\>(source: T): T; 279 280Converts ordinary unobservable data into observable data. For details, see [makeObserved API: Changing Unobservable Data to Observable Data](../../quick-start/arkts-new-makeObserved.md). 281 282**Atomic service API**: This API can be used in atomic services since API version 12. 283 284**System capability**: SystemCapability.ArkUI.ArkUI.Full 285 286**Parameters** 287 288| Name| Type| Mandatory| Description | 289| ------ | ---- | ---- | ------------ | 290| 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).| 291 292**Return value** 293 294| Type| Description | 295| ---- | ------------------------------------------------ | 296| T | Observable data.| 297 298**Example** 299 300```ts 301import { UIUtils } from '@kit.ArkUI'; 302class NonObservedClass { 303 name: string = 'Tom'; 304} 305 306@Entry 307@ComponentV2 308struct Index { 309 observedClass: NonObservedClass = UIUtils.makeObserved(new NonObservedClass()); 310 nonObservedClass: NonObservedClass = new NonObservedClass(); 311 build() { 312 Column() { 313 Text(`observedClass: ${this.observedClass.name}`) 314 .onClick(() => { 315 this.observedClass.name = 'Jane'; // This will trigger a UI update. 316 }) 317 Text(`observedClass: ${this.nonObservedClass.name}`) 318 .onClick(() => { 319 this.nonObservedClass.name = 'Jane'; // This will not trigger a UI update. 320 }) 321 } 322 } 323} 324``` 325 326## StorageDefaultCreator\<T\> 327 328type StorageDefaultCreator\<T\> = () => T; 329 330Obtains the default constructor. 331 332**Atomic service API**: This API can be used in atomic services since API version 12. 333 334**System capability**: SystemCapability.ArkUI.ArkUI.Full 335 336**Return value** 337 338| Type| Description | 339| ---- | ------------------------------------------------ | 340| () => T | Default constructor.| 341 342**Example** 343 344```ts 345import { PersistenceV2 } from '@kit.ArkUI'; 346 347@ObservedV2 348class SampleClass { 349 @Trace id: number = 0; 350 count: number = 1; 351} 352 353@ObservedV2 354class FatherSampleClass { 355 @Trace sampleClass: SampleClass = new SampleClass(); 356} 357 358// Persist the key-value pair with the key SampleClass and the value as an instance of SampleClass(), and assign it to variable source. 359// StorageDefaultCreator refers to the function () => new FatherSampleClass(). 360const source: FatherSampleClass | undefined = PersistenceV2.connect(FatherSampleClass, () => new FatherSampleClass()); 361 362@Entry 363@Component 364struct SampleComp { 365 data: FatherSampleClass | undefined = source; 366 367 build() { 368 Column() { 369 Text(`${this.data?.sampleClass.id}`) 370 } 371 } 372} 373``` 374 375## TypeConstructorWithArgs\<T\> 376 377Represents a class constructor that accepts arbitrary arguments. 378 379**Atomic service API**: This API can be used in atomic services since API version 12. 380 381**System capability**: SystemCapability.ArkUI.ArkUI.Full 382 383### new 384 385new(...args: any): T; 386 387**Atomic service API**: This API can be used in atomic services since API version 12. 388 389**System capability**: SystemCapability.ArkUI.ArkUI.Full 390 391**Parameters** 392 393| Name| Type| Mandatory| Description | 394| ------ | ---- | ---- | ------------ | 395| ...args | any | Yes | Function arguments. | 396 397**Return value** 398 399| Type| Description | 400| ---- | ------------------------------------------------ | 401| T | Instance of the T type.| 402 403**Example** 404 405```ts 406import { PersistenceV2 } from '@kit.ArkUI'; 407 408@ObservedV2 409 // TypeConstructorWithArgs refers to the SampleClass constructor. 410class SampleClass { 411 @Trace id: number = 0; 412 count: number = 1; 413} 414 415@ObservedV2 416class FatherSampleClass { 417 @Trace sampleClass: SampleClass = new SampleClass(); 418} 419 420// Persist the key-value pair with the key SampleClass and the value as an instance of SampleClass(), and assign it to variable source. 421const source: FatherSampleClass | undefined = PersistenceV2.connect(FatherSampleClass, () => new FatherSampleClass()); 422 423@Entry 424@Component 425struct SampleComp { 426 data: FatherSampleClass | undefined = source; 427 428 build() { 429 Column() { 430 Text(`${this.data?.sampleClass.id}`) 431 } 432 } 433} 434``` 435 436## PersistenceErrorCallback 437 438type PersistenceErrorCallback = (key: string, reason: 'quota' | 'serialization' | 'unknown', message: string) => void; 439 440Represents the callback invoked when persistence fails. 441 442**Atomic service API**: This API can be used in atomic services since API version 12. 443 444**System capability**: SystemCapability.ArkUI.ArkUI.Full 445 446**Parameters** 447 448| Name| Type| Mandatory| Description | 449| ------ | ---- | ---- | ------------ | 450| key | string | Yes | Key associated with the error. | 451|reason| 'quota' \| 'serialization' \| 'unknown' | Yes | Type of the error. | 452| message | string | Yes | Additional information about the error. | 453 454**Example** 455 456```ts 457import { PersistenceV2, Type } from '@kit.ArkUI'; 458 459@ObservedV2 460class SampleChild { 461 @Trace id: number = 0; 462 count: number = 10; 463} 464 465@ObservedV2 466export class Sample { 467 // For complex objects, use the @Type decorator to ensure successful serialization. 468 @Type(SampleChild) 469 @Trace sampleChild: SampleChild = new SampleChild(); 470} 471 472// Callback used to receive persistence errors. 473// PersistenceErrorCallback refers to (key: string, reason: string, msg: string) => {console.error(`error key: ${key}, reason: ${reason}, message: ${msg}`);}. 474PersistenceV2.notifyOnError((key: string, reason: string, msg: string) => { 475 console.error(`error key: ${key}, reason: ${reason}, message: ${msg}`); 476}); 477 478@Entry 479@ComponentV2 480struct Index { 481 // 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. 482 // Add @Local to decorate the data property that needs to change the connected object. (Changing the connected object is not recommended.) 483 @Local data: Sample = PersistenceV2.connect(Sample, () => new Sample())!; 484 pageStack: NavPathStack = new NavPathStack(); 485 486 build() { 487 Text(`Index add 1 to data.id: ${this.data.sampleChild.id}`) 488 .fontSize(30) 489 .onClick(() => { 490 this.data.sampleChild.id++; 491 }) 492 } 493} 494``` 495 496## TypeConstructor\<T\> 497 498Class constructor. 499 500**Atomic service API**: This API can be used in atomic services since API version 12. 501 502**System capability**: SystemCapability.ArkUI.ArkUI.Full 503 504### new 505 506new(): T; 507 508**Return value** 509 510| Type| Description | 511| ---- | ------------------------------------------------ | 512| T | Instance of the T type.| 513 514**Atomic service API**: This API can be used in atomic services since API version 12. 515 516**System capability**: SystemCapability.ArkUI.ArkUI.Full 517 518**Example** 519 520```ts 521import { PersistenceV2, Type } from '@kit.ArkUI'; 522 523@ObservedV2 524class SampleChild { 525 @Trace id: number = 0; 526 count: number = 10; 527} 528 529@ObservedV2 530export class Sample { 531 // For complex objects, use the @Type decorator to ensure successful serialization. 532 // TypeConstructor refers to SampleChild. 533 @Type(SampleChild) 534 @Trace sampleChild: SampleChild = new SampleChild(); 535} 536 537@Entry 538@ComponentV2 539struct Index { 540 data: Sample = PersistenceV2.connect(Sample, () => new Sample())!; 541 542 build() { 543 Column() { 544 Text(`Index add 1 to data.id: ${this.data.sampleChild.id}`) 545 .fontSize(30) 546 .onClick(() => { 547 this.data.sampleChild.id++; 548 }) 549 } 550 } 551} 552``` 553 554## TypeDecorator 555 556type TypeDecorator = \<T\>(type: TypeConstructor\<T\>) => PropertyDecorator; 557 558Property decorator. 559 560**Atomic service API**: This API can be used in atomic services since API version 12. 561 562**System capability**: SystemCapability.ArkUI.ArkUI.Full 563 564**Parameters** 565 566| Name| Type| Mandatory| Description | 567| ------ | ---- | ---- | ------------ | 568| type | [TypeConstructor\<T\>](#typeconstructort) | Yes | Type of the class property decorated. | 569 570**Return value** 571 572| Type| Description | 573| ---- | ------------------------------------------------ | 574| PropertyDecorator | Property decorator.| 575 576**Example** 577 578```ts 579import { PersistenceV2, Type } from '@kit.ArkUI'; 580 581@ObservedV2 582class SampleChild { 583 @Trace id: number = 0; 584 count: number = 10; 585} 586 587@ObservedV2 588export class Sample { 589 // For complex objects, use the @Type decorator to ensure successful serialization. 590 // TypeDecorator refers to @Type. 591 @Type(SampleChild) 592 @Trace sampleChild: SampleChild = new SampleChild(); 593} 594 595@Entry 596@ComponentV2 597struct Index { 598 data: Sample = PersistenceV2.connect(Sample, () => new Sample())!; 599 600 build() { 601 Column() { 602 Text(`Index add 1 to data.id: ${this.data.sampleChild.id}`) 603 .fontSize(30) 604 .onClick(() => { 605 this.data.sampleChild.id++; 606 }) 607 } 608 } 609} 610``` 611