• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Constraints on Access Modifiers of Custom Component Member Variables
2
3In state management V1, after you encapsulate a custom component, the invoker cannot determine the input variables as the component input parameters based on the unified standard because the component does not have specific input and output identifiers. You can use the **private** qualifier to prevent the current variable from being externally initialized.
4
5To prevent a state variable from being initialized externally, you can use the **private** qualifier to remind the component caller. However, external initialization must comply with the rules of the decorator. For details, see [Constraints](#constraints).
6
7In ArkTS, use of the access modifiers – **private**, **public**, and **protected** – for custom component member variables must comply with the constraints described in this topic. Build errors will be reported for any incompliance.
8
9Before reading this topic, you are advised to read [State Management Overview](./arkts-state-management-overview.md).
10
11> **NOTE**
12>
13> The constraints on access modifiers of custom component member variables are supported since API version 12.
14
15
16## Constraints
17
18- The regular variables (which do not involve re-rendering) and variables decorated by [\@State](./arkts-state.md), [\@Prop](./arkts-prop.md), [\@Provide](./arkts-provide-and-consume.md), or [\@BuilderParam](./arkts-builderparam.md) can be initialized externally or using local values. However, **private** access is not allowed.
19
20- Variables decorated by [\@StorageLink](./arkts-appstorage.md#storagelink), [\@StorageProp](./arkts-appstorage.md#storageprop), [\@LocalStorageLink](./arkts-localstorage.md#localstoragelink), [\@LocalStorageProp](./arkts-localstorage.md#localstorageprop), or [\@Consume](./arkts-provide-and-consume.md) cannot be initialized externally. Therefore, **public** access is not allowed.
21
22- Variables decorated by [\@Link](./arkts-link.md) or [\@ObjectLink](./arkts-observed-and-objectlink.md) must be initialized externally and local initialization is prohibited. Therefore, **private** access is not allowed.
23
24- Because structs do not support inheritance, none of the preceding variables can be declared as **protected**.
25
26- Variables decorated by [\@Require](./arkts-require.md) must be initialized externally. Therefore, using \@Require and **private** together to decorate regular variables (which do not involve re-rendering) and variables decorated by [\@State](./arkts-state.md), [\@Prop](./arkts-prop.md), [\@Provide](./arkts-provide-and-consume.md), or [\@BuilderParam](./arkts-builderparam.md) is not allowed.
27
28
29## Use Scenarios
30
311. If a member variable is decorated by both **private** and the \@State, \@Prop, \@Provide, or \@BuilderParam decorator, and is initialized through the parent component, a build error is reported.
32
33[Negative Example]
34```ts
35@Entry
36@Component
37struct AccessRestrictions {
38  @Builder
39  buildTest() {
40    Text("Parent builder")
41  }
42
43  build() {
44    Column() {
45      ComponentsChild({
46        state_value: "Hello",
47        prop_value: "Hello",
48        provide_value: "Hello",
49        builder_value: this.buildTest,
50        regular_value: "Hello"
51      })
52    }
53    .width('100%')
54  }
55}
56
57@Component
58struct ComponentsChild {
59  // The private access is not allowed and an alarm is reported.
60  @State private state_value: string = "Hello";
61  // The private access is not allowed and an alarm is reported.
62  @Prop private prop_value: string = "Hello";
63  // The private access is not allowed and an alarm is reported.
64  @Provide private provide_value: string = "Hello";
65  // The private access is not allowed and an alarm is reported.
66  @BuilderParam private builder_value: () => void = this.buildTest;
67  // The private access is not allowed and an alarm is reported.
68  private regular_value: string = "Hello";
69
70  @Builder
71  buildTest() {
72    Text("Child builder")
73  }
74
75  build() {
76    Column() {
77      Text("Hello")
78        .fontSize(50)
79        .fontWeight(FontWeight.Bold)
80    }
81  }
82}
83```
84
85The following are some build error examples:
86
87```ts
88Property 'state_value' is private and can not be initialized through the component constructor.
89Property 'prop_value' is private and can not be initialized through the component constructor.
90Property 'provide_value' is private and can not be initialized through the component constructor.
91Property 'builder_value' is private and can not be initialized through the component constructor.
92Property 'regular_value' is private and can not be initialized through the component constructor.
93```
94
95[Positive Example]
96```ts
97@Entry
98@Component
99struct AccessRestrictions {
100  @Builder
101  buildTest() {
102    Text("Parent builder")
103  }
104
105  build() {
106    Column() {
107      ComponentsChild({
108        state_value: "Hello",
109        prop_value: "Hello",
110        provide_value: "Hello",
111        builder_value: this.buildTest,
112        regular_value: "Hello"
113      })
114    }
115    .width('100%')
116  }
117}
118
119@Component
120struct ComponentsChild {
121  @State state_value: string = "Hello";
122  @Prop prop_value: string = "Hello";
123  @Provide provide_value: string = "Hello";
124  @BuilderParam builder_value: () => void = this.buildTest;
125  regular_value: string = "Hello";
126
127  @Builder
128  buildTest() {
129    Text("Child builder")
130  }
131
132  build() {
133    Column() {
134      Text("Hello")
135        .fontSize(50)
136        .fontWeight(FontWeight.Bold)
137    }
138  }
139}
140```
141
1422. If a member variable is decorated by both **public** and the \@StorageLink, \@StorageProp, \@LocalStorageLink, \@LocalStorageProp, or \@Consume decorator, and is initialized through the parent component, a build error is reported.
143
144[Negative Example]
145```ts
146@Entry
147@Component
148struct AccessRestrictions {
149  @Provide consume_value: string = "Hello";
150  build() {
151    Column() {
152      ComponentChild()
153    }
154    .width('100%')
155  }
156}
157
158@Component
159struct ComponentChild {
160  // The public access is not allowed and an alarm is reported.
161  @LocalStorageProp("sessionLocalProp") public local_prop_value: string = "Hello";
162  // The public access is not allowed and an alarm is reported.
163  @LocalStorageLink("sessionLocalLink") public local_link_value: string = "Hello";
164  // The public access is not allowed and an alarm is reported.
165  @StorageProp("sessionProp") public storage_prop_value: string = "Hello";
166  // The public access is not allowed and an alarm is reported.
167  @StorageLink("sessionLink") public storage_link_value: string = "Hello";
168  // The public access is not allowed and an alarm is reported.
169  @Consume public consume_value: string;
170
171  build() {
172    Column() {
173      Text("Hello")
174        .fontSize(50)
175        .fontWeight(FontWeight.Bold)
176    }
177  }
178}
179```
180
181The following are some build error examples:
182
183```ts
184Property 'local_prop_value' can not be decorated with both @LocalStorageProp and public.
185Property 'local_link_value' can not be decorated with both @LocalStorageLink and public.
186Property 'storage_prop_value' can not be decorated with both @StorageProp and public.
187Property 'storage_link_value' can not be decorated with both @StorageLink and public.
188Property 'consume_value' can not be decorated with both @Consume and public.
189```
190
191[Positive Example]
192```ts
193@Entry
194@Component
195struct AccessRestrictions {
196  @Provide consume_value: string = "Hello";
197  build() {
198    Column() {
199      ComponentChild()
200    }
201    .width('100%')
202  }
203}
204
205@Component
206struct ComponentChild {
207  @LocalStorageProp("sessionLocalProp") local_prop_value: string = "Hello";
208  @LocalStorageLink("sessionLocalLink") local_link_value: string = "Hello";
209  @StorageProp("sessionProp") storage_prop_value: string = "Hello";
210  @StorageLink("sessionLink") storage_link_value: string = "Hello";
211  @Consume consume_value: string;
212  build() {
213    Column() {
214      Text("Hello")
215        .fontSize(50)
216        .fontWeight(FontWeight.Bold)
217    }
218  }
219}
220```
221
2223. If a member variable is decorated by both **private** and the \@Link/ or \@ObjectLink decorator, and is initialized through the parent component, a build error is reported.
223
224[Negative Example]
225```ts
226@Entry
227@Component
228struct AccessRestrictions {
229  @State link_value: string = "Hello";
230  @State objectLink_value: ComponentObj = new ComponentObj();
231  build() {
232    Column() {
233      ComponentChild({link_value: this.link_value, objectLink_value: this.objectLink_value})
234    }
235    .width('100%')
236  }
237}
238
239@Observed
240class ComponentObj {
241  count: number = 0;
242}
243@Component
244struct ComponentChild {
245  // The private access is not allowed and an alarm is reported.
246  @Link private link_value: string;
247  // The private access is not allowed and an alarm is reported.
248  @ObjectLink private objectLink_value: ComponentObj;
249  build() {
250    Column() {
251      Text("Hello")
252        .fontSize(50)
253        .fontWeight(FontWeight.Bold)
254    }
255  }
256}
257```
258
259The following are some build error examples:
260
261```ts
262Property 'link_value' can not be decorated with both @Link and private.
263Property 'objectLink_value' can not be decorated with both @ObjectLink and private.
264```
265
266[Positive Example]
267```ts
268@Entry
269@Component
270struct AccessRestrictions {
271  @State link_value: string = "Hello";
272  @State objectLink_value: ComponentObj = new ComponentObj();
273  build() {
274    Column() {
275      ComponentChild({link_value: this.link_value, objectLink_value: this.objectLink_value})
276    }
277    .width('100%')
278  }
279}
280
281@Observed
282class ComponentObj {
283  count: number = 0;
284}
285@Component
286struct ComponentChild {
287  @Link link_value: string;
288  @ObjectLink objectLink_value: ComponentObj;
289  build() {
290    Column() {
291      Text("Hello")
292        .fontSize(50)
293        .fontWeight(FontWeight.Bold)
294    }
295  }
296}
297```
298
2994. If a member variable is decorated by **protected** and is initialized through the parent component, a build error is reported.
300
301[Negative Example]
302```ts
303@Entry
304@Component
305struct AccessRestrictions {
306  build() {
307    Column() {
308      ComponentChild({regular_value: "Hello"})
309    }
310    .width('100%')
311  }
312}
313
314@Component
315struct ComponentChild {
316  // The protected access is not allowed and an alarm is reported.
317  protected regular_value: string = "Hello";
318  build() {
319    Column() {
320      Text("Hello")
321        .fontSize(50)
322        .fontWeight(FontWeight.Bold)
323    }
324  }
325}
326```
327
328The following are some build error examples:
329
330```ts
331The member attributes of a struct can not be protected.
332```
333
334[Positive Example]
335```ts
336@Entry
337@Component
338struct AccessRestrictions {
339  build() {
340    Column() {
341      ComponentChild({regular_value: "Hello"})
342    }
343    .width('100%')
344  }
345}
346
347@Component
348struct ComponentChild {
349  regular_value: string = "Hello";
350  build() {
351    Column() {
352      Text("Hello")
353        .fontSize(50)
354        .fontWeight(FontWeight.Bold)
355    }
356  }
357}
358```
359
3605. If a member variable is decorated by both **private** and the \@Require, \@State, \@Prop, \@Provide, or \@BuilderParam decorator, and is initialized through the parent component, a build error is reported.
361
362[Negative Example]
363```ts
364@Entry
365@Component
366struct AccessRestrictions {
367  build() {
368    Column() {
369      ComponentChild({prop_value: "Hello"})
370    }
371    .width('100%')
372  }
373}
374@Component
375struct ComponentChild {
376  // The private access is not allowed and an alarm is reported.
377  @Require @Prop private prop_value: string = "Hello";
378  build() {
379    Column() {
380      Text("Hello")
381        .fontSize(50)
382        .fontWeight(FontWeight.Bold)
383    }
384  }
385}
386```
387
388The following are some build error examples:
389
390```ts
391Property 'prop_value' can not be decorated with both @Require and private.
392Property 'prop_value' is private and can not be initialized through the component constructor.
393```
394
395[Positive Example]
396```ts
397@Entry
398@Component
399struct AccessRestrictions {
400  build() {
401    Column() {
402      ComponentChild({prop_value: "Hello"})
403    }
404    .width('100%')
405  }
406}
407@Component
408struct ComponentChild {
409  @Require @Prop prop_value: string = "Hello";
410  build() {
411    Column() {
412      Text("Hello")
413        .fontSize(50)
414        .fontWeight(FontWeight.Bold)
415    }
416  }
417}
418```
419