1# AppStorageV2: Storing Application-wide UI State
2
3To enhance the capability of the state management framework to store global UI status variables of applications, you are advised to use AppStorageV2.
4
5>**NOTE**
6>
7>AppStorageV2 is supported since API version 12.
8>
9>State management V2 is still under development, and some features may be incomplete or not always work as expected.
10
11
12## Overview
13
14AppStorage V2 is a singleton to be created when the application UI is started. Its purpose is to provide central storage for application UI state attributes. And AppStorageV2 retains data during application running. Each attribute is accessed using a unique key, which is a string.
15
16UI components synchronize application state attributes with AppStorageV2. AppStorageV2 can be accessed during implementation of application service logic as well.
17
18AppStorageV2 supports state sharing among multiple UIAbility instances in the [main thread](../application-models/thread-model-stage.md) of an application.
19
20
21## How to Use
22
23### connect: Creating or Obtaining Stored Data
24
25```JavaScript
26static connect<T extends object>(
27    type: TypeConstructorWithArgs<T>,
28    keyOrDefaultCreator?: string | StorageDefaultCreator<T>,
29    defaultCreator?: StorageDefaultCreator<T>
30): T | undefined;
31```
32
33| connect      | Description                                                 |
34| ------------ | ----------------------------------------------------- |
35| Parameter        | **type**: specified type. If no **key** is specified, the name of the **type** is used as the **key**.<br> **keyOrDefaultCreater**: specified key or default constructor.<br> **defaultCreator**: default constructor.                                         |
36| Return value      | After creating or obtaining data, value is returned. Otherwise, **undefined** is returned. |
37
38>**NOTE**
39>
40>1. The third parameter is used when no key is specified or the second parameter is invalid. Otherwise, the second parameter is used.
41>
42>2. If the data has been stored in AppStorageV2, you can obtain the stored data without using the default constructor. Otherwise, you must specify the default constructor. If no constructor is specified, the application exception occurs.
43>
44>3. Ensure that the data types match the key. If different types of data are connected to the same key, the application exception occurs.
45>
46>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.
47>
48>5. When match the key with the [\@Observed](arkts-observed-and-objectlink.md) object, specify the key or customize the **name** attribute.
49
50### remove: Deleting the Stored Data of a Specified Key
51
52```JavaScript
53static remove<T>(keyOrType: string | TypeConstructorWithArgs<T>): void;
54```
55
56| remove       | Description                                                 |
57| ------------ | ----------------------------------------------------- |
58| Parameter        | **keyOrType**: key to be deleted. If the key is of the **Type**, the key to be deleted is the name of the **Type**.                                         |
59| Return value      | None. |
60
61>**NOTE**
62>
63>If a key that does not exist in AppStorage V2 is deleted, a warning is reported.
64
65### keys: Returning All Keys Stored in AppStorageV2
66
67```JavaScript
68static keys(): Array<string>;
69```
70
71| keys         | Description                                                 |
72| ------------ | ----------------------------------------------------- |
73| Parameter        | None.                                        |
74| Return value      | All keys stored in AppStorageV2. |
75
76
77## Constraints
78
791. This singleton must be used together with the UI thread only. Other threads, for example, @Sendable decorator is not supported.
80
812. Types such as collections.Set and collections.Map are not supported.
82
833. Non-buildin types, such as native PixelMap, NativePointer, and ArrayList types, are not supported.
84
85## Use Scenarios
86
87### Storing Data Between Two Pages
88
89Page 1
90```ts
91import { router, AppStorageV2 } from '@kit.ArkUI';
92import { Sample } from '../Sample';
93
94@Entry
95@ComponentV2
96struct Page1 {
97  // Create a KV pair whose key is Sample in AppStorageV2 (if the key exists, the data in AppStorageV2 is returned) and associate it with prop.
98  @Local prop: Sample = AppStorageV2.connect(Sample, () => new Sample())!;
99
100  build() {
101    Column() {
102      Button('Go to page2')
103        .onClick(() => {
104          router.pushUrl({
105            url: 'pages/Page2'
106          })
107        })
108
109      Button('Page1 connect the key Sample')
110        .onClick(() => {
111          // Create a KV pair whose key is Sample in AppStorageV2 (if the key exists, the data in AppStorageV2 is returned) and associate it with prop.
112          this.prop = AppStorageV2.connect(Sample, 'Sample', () => new Sample())!;
113        })
114
115      Button('Page1 remove the key Sample')
116        .onClick(() => {
117          // After being deleted from AppStorageV2, prop will no longer be associated with the value whose key is Sample.
118          AppStorageV2.remove(Sample);
119        })
120
121      Text(`Page1 add 1 to prop.p1: ${this.prop.p1}`)
122        .fontSize(30)
123        .onClick(() => {
124          this.prop.p1++;
125        })
126
127      Text(`Page1 add 1 to prop.p2: ${this.prop.p2}`)
128        .fontSize(30)
129        .onClick(() => {
130          // The page is not re-rendered, but the value of p2 is changed.
131          this.prop.p2++;
132        })
133
134      // Obtain all keys in the current AppStorageV2.
135      Text(`all keys in AppStorage: ${AppStorageV2.keys()}`)
136        .fontSize(30)
137    }
138  }
139}
140```
141
142Page 2
143```ts
144import { AppStorageV2 } from '@kit.ArkUI';
145import { Sample } from '../Sample';
146
147@Entry
148@ComponentV2
149struct Page2 {
150  // Create a KV pair whose key is Sample in AppStorageV2 (if the key exists, the data in AppStorageV2 is returned) and associate it with prop.
151  @Local prop: Sample = AppStorageV2.connect(Sample, () => new Sample())!;
152
153  build() {
154    Column() {
155      Button('Page2 connect the key Sample1')
156        .onClick(() => {
157          // Create a KV pair whose key is Sample1 in AppStorageV2 (if the key exists, the data in AppStorageV2 is returned) and associate it with prop.
158          this.prop = AppStorageV2.connect(Sample, 'Sample1', () => new Sample())!;
159        })
160
161      Text(`Page2 add 1 to prop.p1: ${this.prop.p1}`)
162        .fontSize(30)
163        .onClick(() => {
164          this.prop.p1++;
165        })
166
167      Text(`Page2 add 1 to prop.p2: ${this.prop.p2}`)
168        .fontSize(30)
169        .onClick(() => {
170          // The page is not re-rendered, but the value of p2 is changed, which is performed after re-initialization.
171          this.prop.p2++;
172        })
173
174      // Obtain all keys in the current AppStorageV2.
175      Text(`all keys in AppStorage: ${AppStorageV2.keys()}`)
176        .fontSize(30)
177    }
178  }
179}
180```
181
182Data page
183```ts
184// Data center
185@ObservedV2
186export class Sample {
187  @Trace p1: number = 0;
188  p2: number = 10;
189}
190```
191