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