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