1# ArkUI Subsystem Changelog 2 3## cl.arkui.1 Verification Against Undefined Keys for Decorators 4 5**Access Level** 6 7Public 8 9**Reason for Change** 10 11The **key** value should be verified for all decorators to comply with TypeScript syntax rules. 12 13The following decorators are involved: 14 15@LocalStorageLink, @LocalStorageProp, @StorageProp, @StorageLink, @Provide, @Consume, @Watch 16 17**Change Impact** 18 19If the **key** value of any of the aforementioned decorators is not defined, a compilation error is reported. 20 21This change is a non-compatible change. 22 23**Start API Level** 24 25@LocalStorageLink: API version 9 26 27@LocalStorageProp: API version 9 28 29@StorageProp: API version 7 30 31@StorageLink: API version 7 32 33@Provide: API version 7 34 35@Consume: API version 7 36 37@Watch: API version 7 38 39 40 41**Change Since** 42 43OpenHarmony SDK 5.0.0.13 44 45Example: 46 47``` 48@Entry 49@Component 50struct ComA { 51 // ERROR: Cannot find name 'aaa'. 52 @StorageProp(aaa) storageProp: string = 'storageProp'; 53 // ERROR: Cannot find name 'aaa'. 54 @StorageLink(aaa) storageLink: string = 'storageLink'; 55 // ERROR: Cannot find name 'aaa'. 56 @LocalStorageLink(aaa) localStorageLink: string = 'localStorageLink'; 57 // ERROR: Cannot find name 'aaa'. 58 @LocalStorageProp(aaa) localStorageProp: string = 'localStorageProp'; 59 // ERROR: Cannot find name 'aaa'. 60 @Provide(aaa) provide: string = 'provide'; 61 // ERROR: Cannot find name 'aaa'. 62 @Consume(aaa) consume: number; 63 // ERROR: Cannot find name 'aaa'. 64 @State @Watch(aaa) watch: number = 0; 65 66 build() { 67 } 68} 69 70``` 71 72**Adaptation Guide** 73 74 Make sure the **key** value for the following decorators is defined: @LocalStorageLink, @LocalStorageProp, @StorageProp, @StorageLink, @Provide, @Consume, and @Watch. 75 76``` 77// test.ts 78export let oneKey = 'string'; 79``` 80 81 82 83``` 84 85// index.ets 86import { oneKey } from './test'; 87@Entry 88@Component 89struct ComA { 90 @StorageProp(oneKey) storageProp: string = 'storageProp'; 91 @StorageLink(oneKey) storageLink: string = 'storageLink'; 92 @LocalStorageLink(oneKey) localStorageLink: string = 'localStorageLink'; 93 @LocalStorageProp(oneKey) localStorageProp: string = 'localStorageProp'; 94 @Provide(oneKey) provide: string = 'provide'; 95 @Consume(oneKey) consume: number; 96 97 build() { 98 } 99} 100``` 101 102 103 104 105## cl.arkui.2 Addition of undefined and null Support for AppStorage, LocalStorage, and PersistentStorage 106 107**Access Level** 108 109Public 110 111**Change Impact** 112 113The AppStorage, LocalStorage, and PersistentStorage APIs now accept **null** and **undefined** as input parameters. The @StorageLink, @StorageProp, @LocalStorageLink, and @LocalStorageProp decorators now support **null** and **undefined** types. 114 115Take @StorageLink as an example. If an AppStorage API uses **null** or **undefined** as the initial or target value, then: In the semantics before change, calling the API reports a warning and does not take effect. In the semantics after change, **null** or **undefined** is saved as the initial or target value in AppStorage. This change causes the original application code to crash in the following scenario: 116 117Before change: 118 119```ts 120class PropA { 121 num: number = 100; 122} 123 124AppStorage.setOrCreate("PropA", null); 125AppStorage.has("PropA");// Because null and undefined are not supported, false is returned. 126 127@Entry 128@Component 129struct TestPage { 130 @StorageLink('PropA') propA: PropA = new PropA(); 131 132 build() { 133 Column() { 134 Text(this.propA.num.toString()) // propA is locally initialized to 100. 135 } 136 } 137} 138``` 139 140After change: 141 142```ts 143class PropA { 144 num: number = 100; 145} 146 147AppStorage.setOrCreate("PropA", null); 148AppStorage.has("PropA");// Because null and undefined are supported, true is returned. 149 150@Entry 151@Component 152struct TestPage { 153 @StorageLink('PropA') propA: PropA = new PropA(); 154 155 build() { 156 Column() { 157 Text(this.propA.num.toString()) // propA is initialized with the value null in AppStorage. As a result, JsCrash is triggered during invoking. 158 } 159 } 160} 161``` 162 163**Key API/Component Changes** 164 165AppStorage: **set**, **setOrCreate**, **setAndLink**, **setAndProp** 166 167LocalStorage: **set**, **setOrCreate**, **setAndLink**, **setAndProp** 168 169PersistentStorage: **persistProp** 170 171 172**Start API Level** 173 174This change takes effect since API version 12. 175 176AppStorage 177 178**set**: API version 10 179 180**setOrCreate**: API version 10 181 182**setAndLink**: API version 10 183 184**setAndProp**: API version 10 185 186LocalStorage 187 188**set**: API version 9 189 190**setOrCreate**: API version 9 191 192**setAndLink**: API version 9 193 194**setAndProp**: API version 9 195 196PersistentStorage 197 198**persistProp**: API version 10 199 200**Change Since** 201 202OpenHarmony SDK 5.0.0.13 203 204**Adaptation Guide** 205 2061. Do not use **null** or **undefined** to initialize variables. Use meaningful values instead. 207 2082. Changing a value to **null** or **undefined** will trigger UI re-render. 209 2103. Add a null check to the invoking position. 211 212```ts 213class PropA { 214 num: number = 100; 215} 216 217AppStorage.setOrCreate("PropA", null); 218AppStorage.has("PropA"); // Because null and undefined are supported, true is returned. 219 220@Entry 221@Component 222struct TestPage { 223 @StorageLink('PropA') propA: PropA | null | undefined = new PropA(); 224 225 build() { 226 Column() { 227 Text(this.propA?.num.toString())// Check whether the value is null to prevent crashes caused by null and undefined during invoking. 228 .fontSize(20) 229 Button("Set propA to null") 230 .margin(10) 231 .onClick(() => { 232 this.propA = null; 233 }) 234 Button("Set propA to undefined") 235 .margin(10) 236 .onClick(() => { 237 this.propA = undefined; 238 }) 239 Button("Assign new PropA") 240 .margin(10) 241 .onClick(() => { 242 this.propA = new PropA(); 243 }) 244 } 245 } 246} 247``` 248