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.
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### connect<sup>12+</sup>
30
31static connect\<T extends object\>( <br>
32      type: TypeConstructorWithArgs\<T\>, <br>
33      keyOrDefaultCreator?: string | StorageDefaultCreator\<T\>, <br>
34      defaultCreator?: StorageDefaultCreator\<T\> <br>
35): T | undefined;
36
37Stores 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.
38
39**Atomic service API**: This API can be used in atomic services since API version 12.
40
41**System capability**: SystemCapability.ArkUI.ArkUI.Full
42
43**Parameters**
44
45| Name  | Type  | Mandatory| Description              |
46| -------- | ------ | ---- | ---------------------- |
47| type | TypeConstructorWithArgs\<T\> | Yes  | Type. If no key is specified, the name of the type is used as the key.|
48| keyOrDefaultCreater | string \| StorageDefaultCreator\<T\> | No  | Key, or the constructor for obtaining the default value.|
49| defaultCreator | StorageDefaultCreator\<T\> | No  | Constructor for obtaining the default value.|
50
51>**NOTE**
52>
53>1. The second parameter is used when no key is specified, and the third parameter is used otherwise.
54>
55>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.
56>
57>3. Ensure that the data types match the key. Connecting different types of data to the same key will result in an application exception.
58>
59>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.
60
61**Return value**
62
63| Type                                  | Description                                                        |
64| -------------------------------------- | ------------------------------------------------------------ |
65| T | Returns data if the creation or data acquisition from AppStorageV2 is successful; returns **undefined** otherwise.|
66
67**Example**
68
69```ts
70import { AppStorageV2 } from '@kit.ArkUI';
71
72@ObservedV2
73class SampleClass {
74  @Trace p: number = 0;
75}
76
77// 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.
78const as1: SampleClass | undefined = AppStorageV2.connect(SampleClass, () => new SampleClass());
79
80// 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.
81const as2: SampleClass = AppStorageV2.connect(SampleClass, 'key_as2', () => new SampleClass())!;
82
83// As the key SampleClass already exists in AppStorageV2, the value associated with the key is returned to variable as3.
84const as3: SampleClass = AppStorageV2.connect(SampleClass) as SampleClass;
85```
86
87### remove<sup>12+</sup>
88
89static remove\<T\>(keyOrType: string | TypeConstructorWithArgs\<T\>): void;
90
91Removes 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.
92
93**Atomic service API**: This API can be used in atomic services since API version 12.
94
95**System capability**: SystemCapability.ArkUI.ArkUI.Full
96
97**Parameters**
98
99| Name  | Type  | Mandatory| Description              |
100| -------- | ------ | ---- | ---------------------- |
101| 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.|
102
103>**NOTE**
104>
105>Attempting to remove a key that does not exist in AppStorageV2 will result in a warning.
106
107
108**Example**
109
110<!--code_no_check-->
111```ts
112// Assuming that there is a key named key_as2 in AppStorageV2, the following will remove the corresponding key-value pair from AppStorageV2.
113AppStorageV2.remove('key_as2');
114
115// Assuming that there is a key named SampleClass in AppStorageV2, the following will remove the corresponding key-value pair from AppStorageV2.
116AppStorageV2.remove(SampleClass);
117
118// Assuming there is no key named key_as1 in AppStorageV2, the following will result in a warning.
119AppStorageV2.remove('key_as1');
120```
121
122### keys<sup>12+</sup>
123
124static keys(): Array\<string\>;
125
126Obtains all keys in [AppStorageV2](../../quick-start/arkts-new-appstoragev2.md).
127
128**Atomic service API**: This API can be used in atomic services since API version 12.
129
130**System capability**: SystemCapability.ArkUI.ArkUI.Full
131
132**Parameters**
133
134None.
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
157For details about how to use PersistenceV2, see [PersistenceV2: Persisting Application State](../../quick-start/arkts-new-persistencev2.md).
158
159### connect<sup>12+</sup>
160
161static connect\<T extends object\>( <br>
162      type: TypeConstructorWithArgs\<T\>, <br>
163      keyOrDefaultCreator?: string | StorageDefaultCreator\<T\>, <br>
164      defaultCreator?: StorageDefaultCreator\<T\> <br>
165): T | undefined;
166
167Stores the key-value pair data on the application disk (for persistence). If the given key already exists in [PersistenceV2](../../quick-start/arkts-new-persistencev2.md), it returns the corresponding value; otherwise, it constructs a default value using the constructor for obtaining the default value and returns it. If what is connected is an [\@ObservedV2](../../quick-start/arkts-new-observedV2-and-trace.md) object, changes to the object's [\@Trace](../../quick-start/arkts-new-observedV2-and-trace.md) decorated property will trigger automatic persistence of the entire associated object; changes to non-@Trace-decorated properties will not. If necessary, you can manually persist data by calling the **PersistenceV2.save** API.
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| type | TypeConstructorWithArgs\<T\> | Yes  | Type. If no key is specified, the name of the type is used as the key.|
178| keyOrDefaultCreater | string \| StorageDefaultCreator\<T\> | No  | Key, or the constructor for obtaining the default value.|
179| defaultCreator | StorageDefaultCreator\<T\> | No  | Constructor for obtaining the default value.|
180
181>**NOTE**
182>
183>1. The third parameter is used when no **key** is specified or the second parameter is invalid, and the third parameter is used in all other cases.
184>
185>2. If the data has been stored in PersistenceV2, 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.
186>
187>3. Ensure that the data types match the key. Connecting different types of data to the same key will result in an application exception.
188>
189>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.
190
191**Return value**
192
193| Type                                  | Description                                                        |
194| -------------------------------------- | ------------------------------------------------------------ |
195| T | Returns data if the creation or data acquisition from AppStorageV2 is successful; returns **undefined** otherwise.|
196
197**Example**
198
199```ts
200import { PersistenceV2, Type } from '@kit.ArkUI';
201
202@ObservedV2
203class SampleClass {
204  @Trace p1: number = 0;
205  p2: number = 1;
206}
207
208@ObservedV2
209class FatherSampleClass {
210  @Trace f: SampleClass = new SampleClass();
211}
212
213// Persist the key-value pair with the key SampleClass and the value as an instance of SampleClass(), and assign it to variable as1.
214const as1: FatherSampleClass | undefined = PersistenceV2.connect(FatherSampleClass, () => new FatherSampleClass());
215
216// Persist the key-value pair with the key key_as2 and the value as an instance of SampleClass(), and assign it to variable as2.
217const as2: FatherSampleClass = PersistenceV2.connect(FatherSampleClass, 'key_as2', () => new FatherSampleClass())!;
218
219// As the key SampleClass already exists in PersistenceV2, the value associated with the key is returned to variable as3.
220const as3: FatherSampleClass = PersistenceV2.connect(FatherSampleClass) as FatherSampleClass;
221
222@Entry
223@Component
224struct SampleComp {
225  v: FatherSampleClass = as2;
226
227  build() {
228    Column() {
229      Text(`${this.v.f.p1}`)
230        .onClick(() => {
231          // Automatic persistence
232          this.v.f.p1++;
233        })
234      Text(`${this.v.f.p2}`)
235        .onClick(() => {
236          // Automatic persistence is not available. You need to call the PersistenceV2.save API for manual persistence.
237          this.v.f.p2++;
238        })
239    }
240  }
241}
242```
243
244### remove<sup>12+</sup>
245
246static remove\<T\>(keyOrType: string | TypeConstructorWithArgs\<T\>): void;
247
248Removes the specified key-value pair from [PersistenceV2](../../quick-start/arkts-new-persistencev2.md). If the specified key does not exist in PersistenceV2, the removal will fail.
249
250**Atomic service API**: This API can be used in atomic services since API version 12.
251
252**System capability**: SystemCapability.ArkUI.ArkUI.Full
253
254**Parameters**
255
256| Name  | Type  | Mandatory| Description              |
257| -------- | ------ | ---- | ---------------------- |
258| keyOrType | string \| TypeConstructorWithArgs\<T\> | Yes  | Key to be removed. If a type is specified, the key to be removed is the name of that type.|
259
260>**NOTE**
261>
262>Attempting to remove a key that does not exist in PersistenceV2 will result in a warning.
263
264
265**Example**
266
267<!--code_no_check-->
268```ts
269// Assuming that there is a key named key_as2 in PersistenceV2, the following will remove the corresponding key-value pair from PersistenceV2.
270PersistenceV2.remove('key_as2');
271
272// Assuming that there is a key named SampleClass in PersistenceV2, the following will remove the corresponding key-value pair from PersistenceV2.
273PersistenceV2.remove(SampleClass);
274
275// Assuming there is no key named key_as1 in PersistenceV2, the following will result in a warning.
276PersistenceV2.remove('key_as1');
277```
278
279### keys<sup>12+</sup>
280
281static keys(): Array\<string\>;
282
283Obtains all keys in [PersistenceV2](../../quick-start/arkts-new-persistencev2.md).
284
285**Atomic service API**: This API can be used in atomic services since API version 12.
286
287**System capability**: SystemCapability.ArkUI.ArkUI.Full
288
289**Parameters**
290
291None.
292
293**Return value**
294
295| Type                                  | Description                                                        |
296| -------------------------------------- | ------------------------------------------------------------ |
297| Array\<string\> | All keys in PersistenceV2.|
298
299>**NOTE**
300>
301>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 PersistenceV2.
302
303**Example**
304
305```ts
306// Assuming there are two keys (key_as1 and key_as2) in PersistenceV2, the following will return an array containing these keys and assign it to keys.
307const keys: Array<string> = PersistenceV2.keys();
308```
309
310### save<sup>12+</sup>
311
312static save\<T\>(keyOrType: string | TypeConstructorWithArgs\<T\>): void;
313
314Persists the specified key-value pair data once.
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**Parameters**
321
322| Name  | Type  | Mandatory| Description              |
323| -------- | ------ | ---- | ---------------------- |
324| keyOrType | string \| TypeConstructorWithArgs\<T\> | Yes  | Key to be persisted. If a type is specified, the key for persistence is the name of the type.|
325
326>**NOTE**
327>
328>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.
329>
330>It is useless to manually persist the keys that are not in the **connect** state in the memory.
331
332
333**Example**
334
335<!--code_no_check-->
336```ts
337// Assuming there is a key named key_as2 in PersistenceV2, the following will persist the data for this key-value pair.
338PersistenceV2.save('key_as2');
339
340// Assuming there is a key named SampleClass in PersistenceV2, the following will persist the data for this key-value pair.
341PersistenceV2.remove(SampleClass);
342
343// Assuming there is no key named key_as1 in PersistenceV2, this operation is meaningless.
344PersistenceV2.remove('key_as1');
345```
346
347## UIUtils
348
349Provides APIs for handling data transformations related to state management.
350
351### getTarget<sup>12+</sup>
352
353static getTarget\<T extends object\>(source: T): T;
354
355Obtains 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).
356
357**Atomic service API**: This API can be used in atomic services since API version 12.
358
359**System capability**: SystemCapability.ArkUI.ArkUI.Full
360
361**Parameters**
362
363| Name| Type| Mandatory| Description    |
364| ------ | ---- | ---- | ------------ |
365| source | T    | Yes  | Source object.|
366
367**Return value**
368
369| Type| Description                                            |
370| ---- | ------------------------------------------------ |
371| T    | Original object of the source after the proxy added by the state management framework is removed.|
372
373**Example**
374
375```ts
376import { UIUtils } from '@kit.ArkUI';
377class NonObservedClass {
378  name: string = "Tom";
379}
380let nonObservedClass: NonObservedClass = new NonObservedClass();
381@Entry
382@Component
383struct Index {
384  @State someClass: NonObservedClass = nonObservedClass;
385  build() {
386    Column() {
387      Text(`this.someClass === nonObservedClass: ${this.someClass === nonObservedClass}`) // false
388      Text(`UIUtils.getTarget(this.someClass) === nonObservedClass: ${UIUtils.getTarget(this.someClass) ===
389        nonObservedClass}`) // true
390    }
391  }
392}
393```
394### makeObserved<sup>12+</sup>
395
396static makeObserved\<T extends object\>(source: T): T;
397
398Converts ordinary unobservable data into observable data. For details, see [makeObserved API: Changing Unobservable Data to Observable Data](../../quick-start/arkts-new-makeObserved.md).
399
400**Atomic service API**: This API can be used in atomic services since API version 12.
401
402**System capability**: SystemCapability.ArkUI.ArkUI.Full
403
404**Parameters**
405
406| Name| Type| Mandatory| Description    |
407| ------ | ---- | ---- | ------------ |
408| 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).|
409
410**Return value**
411
412| Type| Description                                            |
413| ---- | ------------------------------------------------ |
414| T    | Observable data.|
415
416**Example**
417
418```ts
419import { UIUtils } from '@kit.ArkUI';
420class NonObservedClass {
421  name: string = 'Tom';
422}
423
424@Entry
425@ComponentV2
426struct Index {
427  observedClass: NonObservedClass = UIUtils.makeObserved(new NonObservedClass());
428  nonObservedClass: NonObservedClass = new NonObservedClass();
429  build() {
430    Column() {
431      Text(`observedClass: ${this.observedClass.name}`)
432        .onClick(() => {
433          this.observedClass.name = 'Jane'; // This will trigger a UI update.
434        })
435      Text(`observedClass: ${this.nonObservedClass.name}`)
436        .onClick(() => {
437          this.nonObservedClass.name = 'Jane'; // This will not trigger a UI update.
438        })
439    }
440  }
441}
442```
443