• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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