1# LazyForEach 2 3> **NOTE** 4> 5> The initial APIs of this module are supported since API version 7. Newly added APIs will be marked with a superscript to indicate their earliest API version. 6 7For details about the development, see [LazyForEach: Lazy Data Loading](../../../ui/state-management/arkts-rendering-control-lazyforeach.md). 8In scenarios involving a large number of child components, LazyForEach, when combined with techniques such as cached list items, dynamic preloading, and component reuse, can significantly improve scrolling frame rates while reducing memory usage. For best practices, see [Optimizing Frame Loss for Long List Loading](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-best-practices-long-list). 9 10## APIs 11 12LazyForEach(dataSource: IDataSource, itemGenerator: (item: any, index: number) => void, keyGenerator?: (item: any, index: number) => string) 13 14**LazyForEach** iterates over provided data sources and creates corresponding components during each iteration. When **LazyForEach** is used in a scrolling container, the framework creates components as required within the visible area of the scrolling container. When a component is out of the visible area, the framework destroys and reclaims the component to reduce memory usage. 15 16**Atomic service API**: This API can be used in atomic services since API version 11. 17 18**System capability**: SystemCapability.ArkUI.ArkUI.Full 19 20**Parameters** 21 22| Name | Type | Mandatory| Description | 23| ------------- | --------------------------------------------------------- | ---- | ------------------------------------------------------------ | 24| dataSource | [IDataSource](#idatasource) | Yes | **LazyForEach** data source. You need to implement related APIs. | 25| itemGenerator | (item: any, index: number) => void | Yes | Child component generation function, which generates a child component for each data item in the array.<br>**NOTE**<br>- (Optional) **item**: data item.<br>(Optional) **index**: index of the data item.<br>- The function body of **itemGenerator** must be included in braces {...}.<br>- **itemGenerator** can and must generate only one child component for each iteration.<br>- The **if** statement is allowed in **itemGenerator**, but you must ensure that each branch of the **if** statement creates a child component of the same type.| 26| keyGenerator | (item: any, index: number) => string | No | ID generation function, which generates a unique and fixed ID for each data item in the data source. Components are updated only when their generated key changes. The **keyGenerator** parameter is optional, but you are advised to provide it so that the development framework can better identify array changes and update components correctly.<br>**NOTE**<br>- (Optional) **item**: data item.<br>(Optional) **index**: index of the data item.<br>- The ID generated for each data item in the data source must be unique.<br>- If **keyGenerator** is not provided, the framework uses the default key generation function, that is, **(item: Object, index: number) => { return viewId + '-' + index.toString(); }**, where the generated key value is only affected by the index.| 27 28> **NOTE** 29> 30> To ensure smooth scrolling and prevent frame drops, avoid time-consuming operations in **keyGenerator** and **itemGenerator** functions. For best practices, see [Optimizing Time-Consuming Operations in the Main Thread: Repeated Rendering](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-time-optimization-of-the-main-thread#section4551193714439). The **JSON.stringify()** method is particularly discouraged for key generation in complex business scenarios. When processing item objects, this serialization method consumes significant computational resources and execution time, which can substantially degrade page rendering performance. For best practices, see [Optimizing Performance Using LazyForEach: Rules for Generating Key Values and Creating Components](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-lazyforeach-optimization#section68711519072). 31 32## IDataSource 33 34**Atomic service API**: This API can be used in atomic services since API version 11. 35 36**System capability**: SystemCapability.ArkUI.ArkUI.Full 37 38### totalCount 39 40totalCount(): number 41 42Obtains the total number of data items. 43 44**Atomic service API**: This API can be used in atomic services since API version 11. 45 46**System capability**: SystemCapability.ArkUI.ArkUI.Full 47 48**Return value** 49 50| Type | Description | 51| ------------------- | --------- | 52| number | Total number of data items, which is subject to the data source.| 53 54### getData 55 56getData(index: number): any 57 58Obtains the data item that matches the specified index. 59 60**Atomic service API**: This API can be used in atomic services since API version 11. 61 62**System capability**: SystemCapability.ArkUI.ArkUI.Full 63 64**Parameters** 65 66| Name| Type | Mandatory| Description | 67| ------ | ------ | ---- | -------------------- | 68| index | number | Yes | Index of the data record to obtain. The value range is [0, data source length - 1].| 69 70**Return value** 71 72| Type | Description | 73| ------------------- | --------- | 74| any | Data item that matches the specified index. The actual type is determined by the data source implementation.| 75 76> **NOTE** 77> 78> To ensure smooth scrolling and prevent frame drops, avoid time-consuming operations in the **getData** function. For best practices, see [Optimizing Time-Consuming Operations in the Main Thread: Repeated Rendering](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-time-optimization-of-the-main-thread#section4551193714439). 79 80### registerDataChangeListener 81 82registerDataChangeListener(listener: DataChangeListener): void 83 84Registers a listener for data changes. 85 86**Atomic service API**: This API can be used in atomic services since API version 11. 87 88**System capability**: SystemCapability.ArkUI.ArkUI.Full 89 90**Parameters** 91 92| Name | Type | Mandatory| Description | 93| -------- | ------------------------------------------- | ---- | -------------- | 94| listener | [DataChangeListener](#datachangelistener7) | Yes | Listener for data changes.| 95 96### unregisterDataChangeListener 97 98unregisterDataChangeListener(listener: DataChangeListener): void 99 100Unregisters the listener for data changes. 101 102**Atomic service API**: This API can be used in atomic services since API version 11. 103 104**System capability**: SystemCapability.ArkUI.ArkUI.Full 105 106**Parameters** 107 108| Name | Type | Mandatory| Description | 109| -------- | ------------------------------------------- | ---- | -------------- | 110| listener | [DataChangeListener](#datachangelistener7) | Yes | Listener for data changes.| 111 112## DataChangeListener<sup>7+</sup> 113 114Listener for data changes. 115 116> **NOTE** 117> 118> In APIs of **DataChangeListener** other than **onDatasetChange**, if the value of **index** is negative, the value is treated as **0** by default. In **onDatasetChange**, if the specified index in a **DataOperation** is outside the data source index range, the corresponding **DataOperation** does not take effect. (In **DataAddOperation**, the value of **index** can equal the data source length.) 119 120**Atomic service API**: This API can be used in atomic services since API version 11. 121 122**System capability**: SystemCapability.ArkUI.ArkUI.Full 123 124### onDataReloaded 125 126onDataReloaded(): void 127 128Invoked when all data is reloaded. For data items whose key remains unchanged, the original child component is used. For data items whose key changes, a new child component is created. 129 130**Atomic service API**: This API can be used in atomic services since API version 11. 131 132**System capability**: SystemCapability.ArkUI.ArkUI.Full 133 134### onDataAdded<sup>(deprecated)</sup> 135 136onDataAdded(index: number): void 137 138Invoked when data is added to the position indicated by the specified index. 139 140> This API is deprecated since API version 8. You are advised to use [onDataAdd](#ondataadd8) instead. 141 142**System capability**: SystemCapability.ArkUI.ArkUI.Full 143 144**Parameters** 145 146| Name| Type | Mandatory| Description | 147| ------ | ------ | ---- | -------------------- | 148| index | number | Yes | Index of the position where data is added. The value range is [0, data source length - 1].| 149 150### onDataMoved<sup>(deprecated)</sup> 151 152onDataMoved(from: number, to: number): void 153 154Invoked when data is moved, that is, when data is swapped between the **from** and **to** positions. 155 156> This API is deprecated since API version 8. You are advised to use [onDataMove](#ondatamove8) instead. 157 158> **NOTE** 159> 160> The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called. 161 162**System capability**: SystemCapability.ArkUI.ArkUI.Full 163 164**Parameters** 165 166| Name| Type | Mandatory| Description | 167| ------ | ------ | ---- | ---------------- | 168| from | number | Yes | Original position of data. The value range is [0, data source length - 1].| 169| to | number | Yes | Target position of data. The value range is [0, data source length - 1].| 170 171### onDataDeleted<sup>(deprecated)</sup> 172 173onDataDeleted(index: number): void 174 175Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly. 176 177> This API is deprecated since API version 8. You are advised to use [onDataDelete](#ondatadelete8) instead. 178 179**System capability**: SystemCapability.ArkUI.ArkUI.Full 180 181**Parameters** 182 183| Name| Type | Mandatory| Description | 184| ------ | ------ | ---- | -------------------- | 185| index | number | Yes | Index of the position where data is deleted. The value range is [0, data source length - 1].| 186 187### onDataChanged<sup>(deprecated)</sup> 188 189onDataChanged(index: number): void 190 191Invoked when data in the position indicated by the specified index is changed. 192 193> This API is deprecated since API version 8. You are advised to use [onDataChange](#ondatachange8) instead. 194 195**System capability**: SystemCapability.ArkUI.ArkUI.Full 196 197**Parameters** 198 199| Name| Type | Mandatory| Description | 200| ------ | ------ | ---- | -------------- | 201| index | number | Yes | Listener for data changes. The value range is [0, data source length - 1].| 202 203### onDataAdd<sup>8+</sup> 204 205onDataAdd(index: number): void 206 207Invoked when data is added to the position indicated by the specified index. 208 209**Widget capability**: This API can be used in ArkTS widgets since API version 10. 210 211**Atomic service API**: This API can be used in atomic services since API version 11. 212 213**System capability**: SystemCapability.ArkUI.ArkUI.Full 214 215**Parameters** 216 217| Name| Type | Mandatory| Description | 218| ------ | ------ | ---- | -------------- | 219| index | number | Yes | Index of the position where data is added. The value range is [0, data source length - 1].| 220 221### onDataMove<sup>8+</sup> 222 223onDataMove(from: number, to: number): void 224 225Invoked when data is moved, that is, when data is swapped between the **from** and **to** positions. 226 227> **NOTE** 228> 229> The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called. 230 231**Atomic service API**: This API can be used in atomic services since API version 11. 232 233**System capability**: SystemCapability.ArkUI.ArkUI.Full 234 235**Parameters** 236 237| Name| Type | Mandatory| Description | 238| ------ | ------ | ---- | ---------------- | 239| from | number | Yes | Original position of data. The value range is [0, data source length - 1].| 240| to | number | Yes | Target position of data. The value range is [0, data source length - 1].| 241 242### onDataDelete<sup>8+</sup> 243 244onDataDelete(index: number): void 245 246Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly. 247 248> **NOTE** 249> 250> Before **onDataDelete** is called, ensure that the corresponding data in **dataSource** has been deleted. Otherwise, undefined behavior will occur during page rendering. 251 252**Atomic service API**: This API can be used in atomic services since API version 11. 253 254**System capability**: SystemCapability.ArkUI.ArkUI.Full 255 256**Parameters** 257 258| Name| Type | Mandatory| Description | 259| ------ | ------ | ---- | -------------------- | 260| index | number | Yes | Index of the position where data is deleted. The value range is [0, data source length - 1].| 261 262### onDataChange<sup>8+</sup> 263 264onDataChange(index: number): void 265 266Invoked when data in the position indicated by the specified index is changed. 267 268**Atomic service API**: This API can be used in atomic services since API version 11. 269 270**System capability**: SystemCapability.ArkUI.ArkUI.Full 271 272**Parameters** 273 274| Name| Type | Mandatory| Description | 275| ------ | ------ | ---- | -------------------- | 276| index | number | Yes | Index of the position where data is changed. The value range is [0, data source length - 1].| 277 278### onDatasetChange<sup>12+</sup> 279 280onDatasetChange(dataOperations: DataOperation[]): void 281 282Invoked when data is processed in batches to notify the component of refreshing. 283 284> **NOTE** 285> 286> This API cannot be used together with other data operation APIs of **DataChangeListener**. For example, in the same **LazyForEach**, if you have called **onDataAdd**, do not call **onDatasetChange**; if you have called **onDatasetChange**, do not call **onDataAdd** or other data operation APIs. Different **LazyForEach** instances on the page do not affect each other. When data is processed in batches within the same **onDatasetChange** callback, if multiple **DataOperation** instances target the same index, only the first **DataOperation** will take effect. 287**Atomic service API**: This API can be used in atomic services since API version 12. 288 289**System capability**: SystemCapability.ArkUI.ArkUI.Full 290 291**Parameters** 292 293| Name | Type | Mandatory| Description | 294| -------------- | ------------------- | ---- | ------------------ | 295| dataOperations | [DataOperation](#dataoperation12)[] | Yes | Array of data operations performed.| 296 297## DataOperation<sup>12+</sup> 298 299> **NOTE** 300> 301> 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. 302 303**Atomic service API**: This API can be used in atomic services since API version 12. 304 305**System capability**: SystemCapability.ArkUI.ArkUI.Full 306 307### DataAddOperation 308 309Represents an operation for adding data. 310 311**Atomic service API**: This API can be used in atomic services since API version 12. 312 313**System capability**: SystemCapability.ArkUI.ArkUI.Full 314 315**Parameters** 316 317| Name| Type | Mandatory| Description | 318| ------ | ------------------------- | ---- | -------------------- | 319| type | [DataOperationType](#dataoperationtype).ADD | Yes | Type of data addition. | 320| index | number | Yes | Index at which to insert the data record. The value range is [0, data source length - 1].| 321| count | number | No | Number of data records to insert.<br>Default value: **1**. | 322| key | string \| Array\<string\> | No | Keys to assign to the inserted data records.| 323 324### DataDeleteOperation 325 326Represents an operation for deleting data. 327 328**Atomic service API**: This API can be used in atomic services since API version 12. 329 330**System capability**: SystemCapability.ArkUI.ArkUI.Full 331 332**Parameters** 333 334| Name| Type | Mandatory| Description | 335| ------ | ------------------------- | ---- | -------------------- | 336| type | [DataOperationType](#dataoperationtype).DELETE | Yes | Type of data deletion. | 337| index | number | Yes | Index at which to start deleting data. The value range is [0, data source length - 1].| 338| count | number | No | Number of data records to delete.<br>Default value: **1**. | 339 340### DataChangeOperation 341 342Represents an operation for changing data. 343 344**Atomic service API**: This API can be used in atomic services since API version 12. 345 346**System capability**: SystemCapability.ArkUI.ArkUI.Full 347 348**Parameters** 349 350| Name| Type | Mandatory| Description | 351| ------ | ------------------------- | ---- | -------------------- | 352| type | [DataOperationType](#dataoperationtype).CHANGE | Yes | Type of data change. | 353| index | number | Yes | Index of the data to be changed. The value range is [0, data source length - 1].| 354| key | string | No | New key to assign to the changed data. The original key is used by default. | 355 356### DataMoveOperation 357 358Represents an operation for moving data. 359 360**Atomic service API**: This API can be used in atomic services since API version 12. 361 362**System capability**: SystemCapability.ArkUI.ArkUI.Full 363 364**Parameters** 365 366| Name| Type | Mandatory| Description | 367| ------ | ------------------------- | ---- | -------------------- | 368| type | [DataOperationType](#dataoperationtype).MOVE | Yes | Type of data movement.| 369| index | [MoveIndex](#moveindex) | Yes | Positions for the movement. The value range is [0, data source length - 1].| 370| key | string | No | New key to assign to the moved data. The original key is used by default.| 371 372#### MoveIndex 373 374**Atomic service API**: This API can be used in atomic services since API version 12. 375 376**System capability**: SystemCapability.ArkUI.ArkUI.Full 377 378**Parameters** 379 380| Name| Type | Mandatory| Description | 381| ------ | --------------- | ---- | ------- | 382| from | number | Yes | Start position for the movement. The value range is [0, data source length - 1].| 383| to | number | Yes | End position for the movement. The value range is [0, data source length - 1].| 384 385### DataExchangeOperation 386 387Represents an operation for exchanging data. 388 389**Atomic service API**: This API can be used in atomic services since API version 12. 390 391**System capability**: SystemCapability.ArkUI.ArkUI.Full 392 393**Parameters** 394 395| Name| Type | Mandatory| Description | 396| ------ | -------------------------- | ---- | ---------------------------- | 397| type | [DataOperationType](#dataoperationtype).EXCHANGE | Yes | Type of data exchange. | 398| index | [ExchangeIndex](#exchangeindex) | Yes | Positions for the exchange. The value range is [0, data source length - 1].| 399| key | [ExchangeKey](#exchangekey) | No | New keys to assign to the exchanged data. The original keys are used by default.| 400 401#### ExchangeIndex 402 403**Atomic service API**: This API can be used in atomic services since API version 12. 404 405**System capability**: SystemCapability.ArkUI.ArkUI.Full 406 407**Parameters** 408 409| Name| Type | Mandatory| Description | 410| ------ | --------------- | ---- | ------- | 411| start | number | Yes | First position for the exchange. The value range is [0, data source length - 1].| 412| end | number | Yes | Second position for the exchange. The value range is [0, data source length - 1].| 413 414#### ExchangeKey 415 416**Atomic service API**: This API can be used in atomic services since API version 12. 417 418**System capability**: SystemCapability.ArkUI.ArkUI.Full 419 420**Parameters** 421 422| Name| Type | Mandatory| Description | 423| ------ | --------------- | ---- | ------- | 424| start | string | Yes | New key to assign to the first position in the exchange. The original key is used by default. | 425| end | string | Yes | New key to assign to the second position in the exchange. The original key is used by default. | 426 427### DataReloadOperation 428 429Represents an operation for reloading data. If the **onDatasetChange** event contains a **DataOperationType.RELOAD** operation, all other operations in the event are ineffective. In such cases, the framework will call **keyGenerator** to perform a comparison of keys with their corresponding values. 430 431**Atomic service API**: This API can be used in atomic services since API version 12. 432 433**System capability**: SystemCapability.ArkUI.ArkUI.Full 434 435**Parameters** 436 437| Name| Type | Mandatory| Description | 438| ------ | ------------------------ | ---- | ---------------- | 439| type | [DataOperationType](#dataoperationtype).RELOAD | Yes | Type of data reloading.| 440 441### DataOperationType 442 443Enumerates the data operation types. 444 445**Atomic service API**: This API can be used in atomic services since API version 12. 446 447**System capability**: SystemCapability.ArkUI.ArkUI.Full 448 449| Name| Value | Description | 450| ------ | ------------------- | -------------------- | 451| ADD | add | Data addition. | 452| DELETE | delete | Data deletion. | 453| CHANGE | change | Data change. | 454| MOVE | move | Data movement.| 455| EXCHANGE | exchange | Data exchange.| 456| RELOAD | reload | Data reloading.| 457