• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# \@Require Decorator: Validating Constructor Input Parameters
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @VictorS67-->
5<!--Designer: @lixingchi1-->
6<!--Tester: @TerryTsao-->
7<!--Adviser: @zhang_yixin13-->
8
9The \@Require decorator is used to declare that specific parameters – either regular variables (not decorated by any other decorator) or variables decorated with \@Prop, \@State, \@Provide, \@BuilderParam, or \@Param – must be passed in to the constructor.
10
11> **NOTE**
12>
13> Validation for \@Prop and \@BuilderParam decorated variables is supported since API version 11.
14>
15> This decorator is supported in ArkTS widgets since API version 11.
16>
17> This decorator can be used in atomic services since API version 11.
18>
19> Validation for regular variables and \@State, \@Provide, or \@Param decorated variables is supported since API version 12.
20
21## Overview
22
23When \@Require is applied to a regular variable or a variable decorated with [\@Prop](./arkts-prop.md), [\@State](./arkts-state.md), [\@Provide](./arkts-provide-and-consume.md), [\@Param](./arkts-new-param.md), or [\@BuilderParam](./arkts-builderparam.md) within a custom component, that variable must be provided during the construction of the custom component.
24
25## Constraints
26
27The \@Require decorator can only decorate a regular variable or a variable decorated with \@Prop, \@State, \@Provide, \@BuilderParam, or \@Param in a struct.
28
29For details about the usage in DevEco Studio Previewer, see [PreviewChecker Inspection Rules](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-previewer-previewchecker-V5).
30
31## Use Scenarios
32
33When the \@Require decorator is used together with a regular variable or a variable decorated with \@Prop, \@State, \@Provide, \@BuilderParam, or \@Param in a child component, the parent component (for example, **Index**) must pass in the variable for constructing the child component. Failure to do so will result in a compilation error.
34
35```ts
36@Entry
37@Component
38struct Index {
39  @State message: string = 'Hello World';
40
41  @Builder
42  buildTest() {
43    Row() {
44      Text('Hello, world')
45        .fontSize(30)
46    }
47  }
48
49  build() {
50    Row() {
51      // All @Require decorated parameters in Child must be passed here.
52      Child({
53        regular_value: this.message,
54        state_value: this.message,
55        provide_value: this.message,
56        initMessage: this.message,
57        message: this.message,
58        buildTest: this.buildTest,
59        initBuildTest: this.buildTest
60      })
61    }
62  }
63}
64
65@Component
66struct Child {
67  @Builder
68  buildFunction() {
69    Column() {
70      Text('initBuilderParam')
71        .fontSize(30)
72    }
73  }
74
75  @Require regular_value: string = 'Hello';
76  @Require @State state_value: string = 'Hello';
77  @Require @Provide provide_value: string = 'Hello';
78  @Require @BuilderParam buildTest: () => void;
79  @Require @BuilderParam initBuildTest: () => void = this.buildFunction;
80  @Require @Prop initMessage: string = 'Hello';
81  @Require @Prop message: string;
82
83  build() {
84    Column() {
85      Text(this.initMessage)
86        .fontSize(30)
87      Text(this.message)
88        .fontSize(30)
89      this.initBuildTest();
90      this.buildTest();
91    }
92    .width('100%')
93    .height('100%')
94  }
95}
96```
97
98
99A custom component **ChildPage** decorated with \@ComponentV2 is initialized by its parent component **ParentPage**. Since \@Param decorated variables are also decorated with \@Require, **ParentPage** must pass these variables with assigned values during construction.
100
101```ts
102@ObservedV2
103class Info {
104  @Trace name: string = '';
105  @Trace age: number = 0;
106}
107
108@ComponentV2
109struct ChildPage {
110  @Require @Param childInfo: Info = new Info();
111  @Require @Param state_value: string = 'Hello';
112
113  build() {
114    Column() {
115      Text(`ChildPage childInfo name :${this.childInfo.name}`)
116        .fontSize(20)
117        .fontWeight(FontWeight.Bold)
118      Text(`ChildPage childInfo age :${this.childInfo.age}`)
119        .fontSize(20)
120        .fontWeight(FontWeight.Bold)
121      Text(`ChildPage state_value age :${this.state_value}`)
122        .fontSize(20)
123        .fontWeight(FontWeight.Bold)
124    }
125  }
126}
127
128@Entry
129@ComponentV2
130struct ParentPage {
131  info1: Info = { name: 'Tom', age: 25 };
132  label1: string = 'Hello World';
133  @Local info2: Info = { name: 'Tom', age: 25 };
134  @Local label2: string = 'Hello World';
135
136  build() {
137    Column() {
138      Text(`info1: ${this.info1.name}  ${this.info1.age}`) // Text1
139        .fontSize(30)
140        .fontWeight(FontWeight.Bold)
141      // The parent component ParentPage performs construction assignment when initializing the child component ChildPage.
142      // Values are passed to the childInfo and state_value properties in ChildPage, which are decorated with @Require and @Param.
143      ChildPage({ childInfo: this.info1, state_value: this.label1 }) // Create a custom component.
144      Line()
145        .width('100%')
146        .height(5)
147        .backgroundColor('#000000').margin(10)
148      Text(`info2: ${this.info2.name}  ${this.info2.age}`) // Text2.
149        .fontSize(30)
150        .fontWeight(FontWeight.Bold)
151      // Similarly, construction assignment is performed when the parent component creates the child component.
152      ChildPage({ childInfo: this.info2, state_value: this.label2 }) // Create a custom component.
153      Line()
154        .width('100%')
155        .height(5)
156        .backgroundColor('#000000').margin(10)
157      Button('change info1&info2')
158        .onClick(() => {
159          this.info1 = { name: 'Cat', age: 18 }; // Text1 is not re-rendered because info1 is not decorated with a decorator and cannot listen for value changes.
160          this.info2 = { name: 'Cat', age: 18 }; // Text2 will be re-rendered because info2 is decorated with a decorator and can listen for value changes.
161          this.label1 = 'Luck'; // No re-rendering occurs because label1 is not decorated with a decorator and cannot listen for value changes.
162          this.label2 = 'Luck'; // Re-rendering occurs because label2 is decorated with a decorator and can listen for value changes.
163        })
164    }
165  }
166}
167```
168
169Since API version 18, \@Require can decorate state variables decorated with \@State, \@Prop, or \@Provide) without requiring a local initial value. These variables can be used directly in the component without compilation errors.
170
171```ts
172@Entry
173@Component
174struct Index {
175  message: string = 'Hello World';
176
177  build() {
178    Column() {
179      Child({ message: this.message })
180    }
181  }
182}
183
184@Component
185struct Child {
186  @Require @State message: string;
187
188  build() {
189    Column() {
190      Text(this.message) // No local initial value needed (since API version 18).
191    }
192  }
193}
194```
195
196## Common Issues
197
198If a parent component fails to pass a parameter required by \@Require in the child component, compilation will fail.
199
200```ts
201@Entry
202@Component
203struct Index {
204  @State message: string = 'Hello World';
205
206  @Builder
207  buildTest() {
208    Row() {
209      Text('Hello, world')
210        .fontSize(30)
211    }
212  }
213
214  build() {
215    Row() {
216      // Error: The @Require decorated parameters are not passed during Child and ChildV2 construction.
217      Child()
218      ChildV2()
219    }
220  }
221}
222
223@Component
224struct Child {
225  @Builder
226  buildFunction() {
227    Column() {
228      Text('initBuilderParam')
229        .fontSize(30)
230    }
231  }
232
233  // @Require decorated parameters that are not passed by the parent component
234  @Require regular_value: string = 'Hello';
235  @Require @State state_value: string = 'Hello';
236  @Require @Provide provide_value: string = 'Hello';
237  @Require @BuilderParam initBuildTest: () => void = this.buildFunction;
238  @Require @Prop initMessage: string = 'Hello';
239
240  build() {
241    Column() {
242      Text(this.initMessage)
243        .fontSize(30)
244      this.initBuildTest();
245    }
246  }
247}
248
249@ComponentV2
250struct ChildV2 {
251  // @Require decorated parameters that are not passed by the parent component
252  @Require @Param message: string;
253
254  build() {
255    Column() {
256      Text(this.message)
257    }
258  }
259}
260```
261