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