• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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