1# \@Once: Implementing Initialization Once 2 3 4To initialize data only once and deny subsequent changes, you can use \@Once decorator together with \@Param decorator. 5 6 7> **NOTE** 8> 9> The \@Once decorator is supported in custom components decorated by \@ComponentV2 since API version 12. 10> 11>State management V2 is still under development, and some features may be incomplete or not always work as expected. 12 13 14 15## Overview 16 17The \@Once decorator accepts values passed in only during variable initialization. When the data source changes, the decorator does not synchronize the changes to child components: 18 19- \@Once must be used with \@Param. Using it independently or with other decorators is not allowed. 20- \@Once does not affect the observation capability of \@Param. Only changes in data source are intercepted. 21- The sequence of the variables decorated by \@Once and \@Param does not affect the actual features. 22- When \@Once and \@Param are used together, you can change the value of \@Param variables locally. 23 24## Rules of Use 25 26As an auxiliary decorator, the \@Once decorator does not have requirements on the decoration type and the capability of observing variables. 27 28| \@Once Variable Decorator| Description | 29| ---------------- | ----------------------------------------- | 30| Decorator parameters | None. | 31| Condition | It cannot be used independently and must be used together with the \@Param decorator.| 32 33 34## Constraints 35 36- \@Once can be used only in custom components decorated by \@ComponentV2 and can be used only with \@Param. 37 38 ```ts 39 @ComponentV2 40 struct CompA { 41 @Param @Once onceParam: string = "onceParam"; // Correct usage. 42 @Once onceStr: string = "Once"; // Incorrect usage. @Once cannot be used independently. 43 @Local @Once onceLocal: string = "onceLocal"; // Incorrect usage. @Once cannot be used with @Local. 44 } 45 @Component 46 struct Index { 47 @Once @Param onceParam: string = "onceParam"; // Incorrect usage. 48 } 49 ``` 50 51- The order of \@Once and \@Param does not matter. Both \@Param \@Once and \@Once \@Param are correct. 52 53 ```ts 54 @ComponentV2 55 struct CompA { 56 @Param @Once param1: number; 57 @Once @Param param2: number; 58 } 59 ``` 60 61## Use Scenarios 62 63### Initializing Variables Only Once 64 65\@Once is used in the scenario where the expected variables synchronize the data source once during initialization and then stop synchronizing the subsequent changes. 66 67```ts 68@ComponentV2 69struct CompA { 70 @Param @Once onceParam: string = ''; 71 build() { 72 Column() { 73 Text(`onceParam: ${this.onceParam}`) 74 } 75 } 76} 77@Entry 78@ComponentV2 79struct CompB { 80 @Local message: string = "Hello World"; 81 build() { 82 Column() { 83 Text(`Parent message: ${this.message}`) 84 Button("change message") 85 .onClick(() => { 86 this.message = "Hello Tomorrow"; 87 }) 88 CompA({ onceParam: this.message }) 89 } 90 } 91} 92``` 93 94### Changing the \@Param Variables Locally 95 96When \@Once is used together with \@Param, the constraint that \@Param cannot be changed locally can be removed, and this change triggers UI re-rendering. In this case, using \@Param and \@Once is equivalent to using \@Local. The difference is that \@Param and \@Once can accept the external initialization passed in. 97 98```ts 99@ObservedV2 100class Info { 101 @Trace name: string; 102 constructor(name: string) { 103 this.name = name; 104 } 105} 106@ComponentV2 107struct Child { 108 @Param @Once onceParamNum: number = 0; 109 @Param @Once @Require onceParamInfo: Info; 110 111 build() { 112 Column() { 113 Text(`Child onceParamNum: ${this.onceParamNum}`) 114 Text(`Child onceParamInfo: ${this.onceParamInfo.name}`) 115 Button("changeOnceParamNum") 116 .onClick(() => { 117 this.onceParamNum++; 118 }) 119 Button("changeParamInfo") 120 .onClick(() => { 121 this.onceParamInfo = new Info("Cindy"); 122 }) 123 } 124 } 125} 126@Entry 127@ComponentV2 128struct Index { 129 @Local localNum: number = 10; 130 @Local localInfo: Info = new Info("Tom"); 131 132 build() { 133 Column() { 134 Text(`Parent localNum: ${this.localNum}`) 135 Text(`Parent localInfo: ${this.localInfo.name}`) 136 Button("changeLocalNum") 137 .onClick(() => { 138 this.localNum++; 139 }) 140 Button("changeLocalInfo") 141 .onClick(() => { 142 this.localInfo = new Info("Cindy"); 143 }) 144 Child({ 145 onceParamNum: this.localNum, 146 onceParamInfo: this.localInfo 147 }) 148 } 149 } 150} 151``` 152