• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# \@Require Decorator: Validating Constructor Input Parameters
2
3
4\@Require is a decorator for declaring that parameters – regular variables (those not decorated by any decorator) or variables decorated by \@Prop, \@State, \@Provide, or \@BuilderParam – must be passed in to the constructor.
5
6
7> **NOTE**
8>
9> Validation for \@Prop and \@BuilderParam decorated variables is supported since API version 11.
10>
11> This decorator can be used in atomic services since API version 11.
12>
13> Validation for regular variables and \@State or \@Provide decorated variables is supported since API version 12.
14
15
16## Overview
17
18When \@Require is used together with a regular variable or a variable decorated by \@Prop, \@State, \@Provide, \@Param, or \@BuilderParam in a custom component, the variable must be passed from the parent component during construction of the custom component.
19
20## Constraints
21
22The \@Require decorator can only decorate a regular variable or a variable decorated by \@Prop, \@State, \@Provide, or \@BuilderParam in a struct.
23
24For 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).
25
26## Use Scenarios
27
28When the \@Require decorator is used together with a regular variable or a variable decorated by \@Prop, \@State, \@Provide, or \@BuilderParam in the **Child** component, the parent component **Index** must pass in the variable for constructing the **Child** component. Otherwise, the compilation fails.
29
30```ts
31@Entry
32@Component
33struct Index {
34  @State message: string = 'Hello World';
35
36  @Builder buildTest() {
37    Row() {
38      Text('Hello, world')
39        .fontSize(30)
40    }
41  }
42
43  build() {
44    Row() {
45      Child({ regular_value: this.message, state_value: this.message, provide_value: this.message, initMessage: this.message, message: this.message,
46        buildTest: this.buildTest, initBuildTest: this.buildTest })
47    }
48  }
49}
50
51@Component
52struct Child {
53  @Builder buildFunction() {
54    Column() {
55      Text('initBuilderParam')
56        .fontSize(30)
57    }
58  }
59  @Require regular_value: string = 'Hello';
60  @Require @State state_value: string = "Hello";
61  @Require @Provide provide_value: string = "Hello";
62  @Require @BuilderParam buildTest: () => void;
63  @Require @BuilderParam initBuildTest: () => void = this.buildFunction;
64  @Require @Prop initMessage: string = 'Hello';
65  @Require @Prop message: string;
66
67  build() {
68    Column() {
69      Text(this.initMessage)
70        .fontSize(30)
71      Text(this.message)
72        .fontSize(30)
73      this.initBuildTest();
74      this.buildTest();
75    }
76    .width('100%')
77    .height('100%')
78  }
79}
80```
81
82 ![img](figures/9e2d58bc-b0e1-4613-934b-8e4237bd5c05.png)
83
84@ComponentV2 decorated custom component **ChildPage** is initialized through the parent component **ParentPage**. Because \@Param is decorated by @Require, **ParentPage** must be constructed and assigned a value.
85
86```ts
87@ObservedV2
88class Info {
89  @Trace name: string = '';
90  @Trace age: number = 0;
91}
92
93@ComponentV2
94struct ChildPage {
95  @Require @Param childInfo: Info = new Info();
96  @Require @Param state_value: string = "Hello";
97  build() {
98    Column() {
99      Text(`ChildPage childInfo name :${this.childInfo.name}`)
100        .fontSize(20)
101        .fontWeight(FontWeight.Bold)
102      Text(`ChildPage childInfo age :${this.childInfo.age}`)
103        .fontSize(20)
104        .fontWeight(FontWeight.Bold)
105      Text(`ChildPage state_value age :${this.state_value}`)
106        .fontSize(20)
107        .fontWeight(FontWeight.Bold)
108    }
109  }
110}
111
112@Entry
113@ComponentV2
114struct ParentPage {
115  info1: Info = { name: "Tom", age: 25 };
116  label1: string = "Hello World";
117  @Local info2: Info = { name: "Tom", age: 25 };
118  @Local label2: string = "Hello World";
119
120  build() {
121    Column() {
122      Text(`info1: ${this.info1.name}  ${this.info1.age}`) // Text1
123        .fontSize(30)
124        .fontWeight(FontWeight.Bold)
125      ChildPage({ childInfo: this.info1, state_value: this.label1}) // Calling a custom component.
126      Line()
127        .width('100%')
128        .height(5)
129        .backgroundColor('#000000').margin(10)
130      Text(`info2: ${this.info2.name}  ${this.info2.age}`) // Text2
131        .fontSize(30)
132        .fontWeight(FontWeight.Bold)
133      ChildPage({ childInfo: this.info2, state_value: this.label2}) // Calling a custom component.
134      Line()
135        .width('100%')
136        .height(5)
137        .backgroundColor('#000000').margin(10)
138      Button("change info1&info2")
139        .onClick(() => {
140          this.info1 = { name: "Cat", age: 18} // Text1 is not re-rendered because no decorator is used to listen for value changes.
141          this.info2 = { name: "Cat", age: 18} // Text2 is re-rendered because a decorator is used to listen for value changes.
142          this.label1 = "Luck"; // ChildPage is not re-rendered because no decorator is used to listen for value changes.
143          this.label2 = "Luck"; // ChildPage is re-rendered because a decorator is used to listen for value changes.
144        })
145    }
146  }
147}
148```
149
150Since API version 16, use \@Require to decorate the \@State, \@Prop, or \@Provide decorated state variables. These state variables can be directly used in components without local initial values and no compilation error is reported.
151
152```ts
153@Entry
154@Component
155struct Index {
156  message: string = 'Hello World';
157  build() {
158    Column() {
159      Child({ message: this.message })
160    }
161  }
162}
163@Component
164struct Child {
165  @Require @State message: string;
166  build() {
167    Column() {
168      Text(this.message) // Compilation succeeds since API version 16.
169    }
170  }
171}
172```
173
174## Incorrect Usage
175
176```ts
177@Entry
178@Component
179struct Index {
180  @State message: string = 'Hello World';
181
182  @Builder buildTest() {
183    Row() {
184      Text('Hello, world')
185        .fontSize(30)
186    }
187  }
188
189  build() {
190    Row() {
191      Child()
192    }
193  }
194}
195
196@Component
197struct Child {
198  @Builder buildFunction() {
199    Column() {
200      Text('initBuilderParam')
201        .fontSize(30)
202    }
203  }
204  // As @Require is used here, parameters must be passed in to the constructor.
205  @Require regular_value: string = 'Hello';
206  @Require @State state_value: string = "Hello";
207  @Require @Provide provide_value: string = "Hello";
208  @Require @BuilderParam initBuildTest: () => void = this.buildFunction;
209  @Require @Prop initMessage: string = 'Hello';
210
211  build() {
212    Column() {
213      Text(this.initMessage)
214        .fontSize(30)
215      this.initBuildTest();
216    }
217  }
218}
219```
220