1# \@Link Decorator: Implementing Two-Way Synchronization Between Parent and Child Components 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @jiyujia926--> 5<!--Designer: @s10021109--> 6<!--Tester: @TerryTsao--> 7<!--Adviser: @zhang_yixin13--> 8 9 10An \@Link decorated variable creates two-way synchronization with its corresponding data source in parent component. 11 12Before reading this topic, you are advised to understand the basic usage of [\@State](./arkts-state.md). For best practices, see [State Management](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-status-management). 13 14> **NOTE** 15> 16> This decorator can be used in ArkTS widgets since API version 9. 17> 18> This decorator can be used in atomic services since API version 11. 19 20## Overview 21 22An \@Link decorated variable in a child component shares the same value with a variable in its parent component. 23 24 25## Usage Rules 26 27| \@Link Decorator | Description | 28| ---------------------------------------- | ------------------------------------------------------------ | 29| Parameters | N/A | 30| Synchronization type | Two-way:<br>The state variable in the parent component can be synchronized with the child component \@Link in a two-way manner. Changes to either will be synchronized to the other. | 31| Allowed variable types | Object, class, string, number, Boolean, enum, and array of these types.<br>[Date type](#decorating-variables-of-the-date-type).<br>Union types defined by the ArkUI framework, for example, [Length](../../reference/apis-arkui/arkui-ts/ts-types.md#length), [ResourceStr](../../reference/apis-arkui/arkui-ts/ts-types.md#resourcestr), and [ResourceColor](../../reference/apis-arkui/arkui-ts/ts-types.md#resourcecolor).<br>The type must be specified and match the two-way bound state variable type of the parent component.<br>For details about the scenarios of supported types, see [Observed Changes](#observed-changes).<br>The **any** type is not supported.<br>(Applicable to API version 11 or later) [Map](#decorating-variables-of-the-map-type) and [Set](#decorating-variables-of-the-set-type) types, and union types of the supported types, for example: **string\| number, string \| undefined**, or **ClassA \| null**. For details, see [Union Type Support](#union-type-support).<br>**NOTE**<br>When using **undefined** and **null**, explicitly specify the type to comply with TypeScript type checking. Example: **@Link a: string \| undefined**. | 32| Initial value for the decorated variable | Initialization of the decorated variables is forbidden. | 33 34 35## Variable Transfer/Access Rules 36 37| Transfer/Access | Description | 38| ---------- | ---------------------------------------- | 39| Initialization and update from the parent component| Mandatory.<br>- A two-way synchronization relationship can be established with an \@State, \@StorageLink, or \@Link decorated variable in the parent component. An @Link decorated variable can be initialized from an [\@State](./arkts-state.md), @Link, [\@Prop](./arkts-prop.md), [\@Provide](./arkts-provide-and-consume.md), [\@Consume](./arkts-provide-and-consume.md), [\@ObjectLink](./arkts-observed-and-objectlink.md), [\@StorageLink](./arkts-appstorage.md#storagelink), [\@StorageProp](./arkts-appstorage.md#storageprop), [\@LocalStorageLink](./arkts-localstorage.md#localstoragelink), or [\@LocalStorageProp](./arkts-localstorage.md#localstorageprop) decorated variable in the parent component.<br>- Since API version 9, the syntax for initializing the child component \@Link from the parent component \@State is **Comp({ aLink: this.aState })**, and **Comp({aLink: $aState})** is also supported.| 40| Child component initialization | Supported; can be used to initialize a regular variable or \@State, \@Link, \@Prop, or \@Provide decorated variable in the child component.| 41| Access from outside the component | Private, accessible only within the component. | 42 43 **Figure 1** Initialization rules 44 45 46 47 48## Observed Changes and Behavior 49 50 51### Observed Changes 52 53- When the decorated variable is of the Boolean, string, or number type, its value change can be observed. For details, see [Using \@Link with Primitive and Class Types](#using-link-with-primitive-and-class-types). 54 55- When the decorated variable is of the class or Object type, its value change and value changes of all its attributes, that is, the attributes that **Object.keys(observedObject)** returns, can be observed. For details, see [Using \@Link with Primitive and Class Types](#using-link-with-primitive-and-class-types). 56 57- When the decorated variable is of the array type, the addition, deletion, and updates of array items can be observed. For details, see [Using \@Link with Array Types](#using-link-with-array-types). 58 59- When the decorated object is of the Date type, the following changes can be observed: (1) complete **Date** object reassignment; (2) property changes caused by calling **setFullYear**, **setMonth**, **setDate**, **setHours**, **setMinutes**, **setSeconds**, **setMilliseconds**, **setTime**, **setUTCFullYear**, **setUTCMonth**, **setUTCDate**, **setUTCHours**, **setUTCMinutes**, **setUTCSeconds**, or **setUTCMilliseconds**. 60 61 62- When the decorated object is of the **Map** type, the following changes can be observed: (1) complete **Map** object reassignment; (2) changes caused by calling **set**, **clear**, or **delete**. For details, see [Decorating Variables of the Map Type](#decorating-variables-of-the-map-type). 63 64- When the decorated object is of the **Set** type, the following changes can be observed: (1) complete **Set** object reassignment; (2) changes caused by calling **add**, **clear**, or **delete**. For details, see [Decorating Variables of the Set Type](#decorating-variables-of-the-set-type). 65### Framework Behavior 66 67An \@Link decorated variable shares the lifecycle of its owning component. 68 69To understand the value initialization and update mechanism of the \@Link decorated variable, it is necessary to consider the parent component and the initial render and update process of the child component that owns the \@Link decorated variable (in this example, the \@State decorated variable in the parent component is used). 70 711. Initial render: The execution of the parent component's **build()** creates an instance of the child component. The initialization process is as follows: 72 1. An \@State decorated variable of the parent component is specified to initialize the child component's \@Link decorated variable. The child component's \@Link decorated variable value remains synchronized with its source variable, enabling two-way data synchronization. 73 2. The parent component's \@State wrapper variable instance is passed to the child component through the child's constructor. When the child component's \@Link wrapper instance receives a reference to the parent's \@State variable, it registers itself with that parent \@State variable. 74 752. Update of the \@Link source: When the state variable in the parent component is updated, the \@Link decorated variable in the related child component is updated. Procedure: 76 1. As indicated in the initial rendering step, the child component's \@Link wrapper class registers the current **this** pointer with the parent component. When the parent component's \@State variable is changed, all built-in components and state variables (such as the \@Link wrapper instance) that depend on it are traversed and updated. 77 2. After the \@Link wrapper instance is updated, all built-in components that depend on the \@Link decorated variable in the child component are notified of the update. In this way, the parent component has the state data of the child components synchronized. 78 793. Update of \@Link: After the \@Link decorated variable in the child component is updated, the following steps are performed (the \@State decorated variable in the parent component is used): 80 1. After the \@Link decorated variable is updated, the **set** method of the parent component's \@State wrapper instance is called to synchronize the new value back to the parent component. 81 2. The \@Link in the child component and \@State in the parent component each update their respective dependent UI components through independent dependency traversals, achieving synchronized state while maintaining proper UI consistency. 82 83 84## Constraints 85 861. The \@Link decorator cannot be used in custom components decorated by [\@Entry](./arkts-create-custom-components.md#entry). 87 882. Variables decorated with \@Link do not support local initialization. Any attempt to perform local initialization on them will result in a compilation error. 89 90 ```ts 91 // Incorrect usage. An error is reported during compilation. 92 @Link count: number = 10; 93 94 // Correct usage. 95 @Link count: number; 96 ``` 97 983. The type of a variable decorated with \@Link must match the type of its data source. The framework throws a runtime error for any type mismatch. 99 100 **Incorrect Usage** 101 102 ```ts 103 class Info { 104 info: string = 'Hello'; 105 } 106 107 class Cousin { 108 name: string = 'Hello'; 109 } 110 111 @Component 112 struct Child { 113 // Incorrect usage: type mismatch between @Link and the @State data source. 114 @Link test: Cousin; 115 116 build() { 117 Text(this.test.name) 118 } 119 } 120 121 @Entry 122 @Component 123 struct LinkExample { 124 @State info: Info = new Info(); 125 126 build() { 127 Column() { 128 // Incorrect usage: type mismatch between @Link and the @State data source. 129 Child({test: new Cousin()}) 130 } 131 } 132 } 133 ``` 134 135 **Correct Usage** 136 137 ```ts 138 class Info { 139 info: string = 'Hello'; 140 } 141 142 @Component 143 struct Child { 144 // Correct usage. 145 @Link test: Info; 146 147 build() { 148 Text(this.test.info) 149 } 150 } 151 152 @Entry 153 @Component 154 struct LinkExample { 155 @State info: Info = new Info(); 156 157 build() { 158 Column() { 159 // Correct usage. 160 Child({test: this.info}) 161 } 162 } 163 } 164 ``` 165 1664. Variables decorated with \@Link can be initialized only by state variables. Using regular variables for initialization causes compilation warnings and runtime crashes. 167 168 **Incorrect Usage** 169 170 ```ts 171 class Info { 172 info: string = 'Hello'; 173 } 174 175 @Component 176 struct Child { 177 @Link msg: string; 178 @Link info: string; 179 180 build() { 181 Text(this.msg + this.info) 182 } 183 } 184 185 @Entry 186 @Component 187 struct LinkExample { 188 @State message: string = 'Hello'; 189 @State info: Info = new Info(); 190 191 build() { 192 Column() { 193 // Incorrect usage. Regular variables cannot initialize @Link decorated variables. 194 Child({msg: 'World', info: this.info.info}) 195 } 196 } 197 } 198 ``` 199 200 **Correct Usage** 201 202 ```ts 203 class Info { 204 info: string = 'Hello'; 205 } 206 207 @Component 208 struct Child { 209 @Link msg: string; 210 @Link info: Info; 211 212 build() { 213 Text(this.msg + this.info.info) 214 } 215 } 216 217 @Entry 218 @Component 219 struct LinkExample { 220 @State message: string = 'Hello'; 221 @State info: Info = new Info(); 222 223 build() { 224 Column() { 225 // Correct usage. 226 Child({msg: this.message, info: this.info}) 227 } 228 } 229 } 230 ``` 231 2325. Variables decorated with \@Link cannot be of the function type. If a function-type variable is decorated with \@Link, the framework throws a runtime error. 233 234 235## Use Scenarios 236 237 238### Using \@Link with Primitive and Class Types 239 240In the following example, after **Parent View: Set yellowButton** and **Parent View: Set GreenButton** of the parent component **ShufflingContainer** are clicked, the change in the parent component is synchronized to the child components. 241 242 1. After buttons of the child components **GreenButton** and **YellowButton** are clicked, the child components (@Link decorated variables) change accordingly. Due to the two-way synchronization relationship between @Link and @State, the changes are synchronized to the parent component. 243 244 2. When a button in the parent component **ShufflingContainer** is clicked, the parent component's @State decorated variable changes, and the changes are synchronized to the child components, which are then updated accordingly. 245 246```ts 247class GreenButtonState { 248 width: number = 0; 249 250 constructor(width: number) { 251 this.width = width; 252 } 253} 254 255@Component 256struct GreenButton { 257 @Link greenButtonState: GreenButtonState; 258 259 build() { 260 Button('Green Button') 261 .width(this.greenButtonState.width) 262 .height(40) 263 .backgroundColor('#64bb5c') 264 .fontColor('#FFFFFF') 265 .onClick(() => { 266 if (this.greenButtonState.width < 700) { 267 // Update the attribute of the class. The change can be observed and synchronized back to the parent component. 268 this.greenButtonState.width += 60; 269 } else { 270 // Update the class. The change can be observed and synchronized back to the parent component. 271 this.greenButtonState = new GreenButtonState(180); 272 } 273 }) 274 } 275} 276 277@Component 278struct YellowButton { 279 @Link yellowButtonState: number; 280 281 build() { 282 Button('Yellow Button') 283 .width(this.yellowButtonState) 284 .height(40) 285 .backgroundColor('#f7ce00') 286 .fontColor('#FFFFFF') 287 .onClick(() => { 288 // The change of the decorated variable of a primitive type in the child component can be synchronized back to the parent component. 289 this.yellowButtonState += 40.0; 290 }) 291 } 292} 293 294@Entry 295@Component 296struct ShufflingContainer { 297 @State greenButtonState: GreenButtonState = new GreenButtonState(180); 298 @State yellowButtonProp: number = 180; 299 300 build() { 301 Column() { 302 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) { 303 // Primitive type @Link in the child component synchronized from @State in the parent component. 304 Button('Parent View: Set yellowButton') 305 .width(this.yellowButtonProp) 306 .height(40) 307 .margin(12) 308 .fontColor('#FFFFFF') 309 .onClick(() => { 310 this.yellowButtonProp = (this.yellowButtonProp < 700) ? this.yellowButtonProp + 40 : 100; 311 }) 312 // Class type @Link in the child component synchronized from @State in the parent component. 313 Button('Parent View: Set GreenButton') 314 .width(this.greenButtonState.width) 315 .height(40) 316 .margin(12) 317 .fontColor('#FFFFFF') 318 .onClick(() => { 319 this.greenButtonState.width = (this.greenButtonState.width < 700) ? this.greenButtonState.width + 100 : 100; 320 }) 321 // Initialize the class type @Link. 322 GreenButton({ greenButtonState: this.greenButtonState }).margin(12) 323 // Initialize the primitive type @Link. 324 YellowButton({ yellowButtonState: this.yellowButtonProp }).margin(12) 325 } 326 } 327 } 328} 329``` 330 331 332 333### Using \@Link with Array Types 334 335 336```ts 337@Component 338struct Child { 339 @Link items: number[]; 340 341 build() { 342 Column() { 343 Button(`Button1: push`) 344 .margin(12) 345 .width(312) 346 .height(40) 347 .fontColor('#FFFFFF') 348 .onClick(() => { 349 this.items.push(this.items.length + 1); 350 }) 351 Button(`Button2: replace whole item`) 352 .margin(12) 353 .width(312) 354 .height(40) 355 .fontColor('#FFFFFF') 356 .onClick(() => { 357 this.items = [100, 200, 300]; 358 }) 359 } 360 } 361} 362 363@Entry 364@Component 365struct Parent { 366 @State arr: number[] = [1, 2, 3]; 367 368 build() { 369 Column() { 370 Child({ items: $arr }) 371 .margin(12) 372 ForEach(this.arr, 373 (item: number) => { 374 Button(`${item}`) 375 .margin(12) 376 .width(312) 377 .height(40) 378 .backgroundColor('#11a2a2a2') 379 .fontColor('#e6000000') 380 }, 381 (item: ForEachInterface) => item.toString() 382 ) 383 } 384 } 385} 386``` 387 388 389 390The ArkUI framework can observe the addition, deletion, and replacement of array items. In the preceding example, both \@State and \@Link decorated variables are declared as the **number[]** type. It is important to note that defining @Link as a number type (for example, \@Link item: number) is not supported. In addition, the framework does not support creating child components in the parent component by using individual data items from the \@State decorated array. For scenarios requiring this type of implementation, use [\@Prop](arkts-prop.md) and [\@Observed](./arkts-observed-and-objectlink.md). 391 392### Decorating Variables of the Map Type 393 394> **NOTE** 395> 396> Since API version 11, \@Link supports the Map type. 397 398In this example, the **value** variable is of the Map\<number, string\> type. When the button is clicked, the value of **message** changes, and the UI is re-rendered. 399 400```ts 401@Component 402struct Child { 403 @Link value: Map<number, string>; 404 405 build() { 406 Column() { 407 ForEach(Array.from(this.value.entries()), (item: [number, string]) => { 408 Text(`${item[0]}`).fontSize(30) 409 Text(`${item[1]}`).fontSize(30) 410 Divider() 411 }) 412 Button('child init map').onClick(() => { 413 this.value = new Map([[0, "a"], [1, "b"], [3, "c"]]); 414 }) 415 Button('child set new one').onClick(() => { 416 this.value.set(4, "d"); 417 }) 418 Button('child clear').onClick(() => { 419 this.value.clear(); 420 }) 421 Button('child replace the first one').onClick(() => { 422 this.value.set(0, "aa"); 423 }) 424 Button('child delete the first one').onClick(() => { 425 this.value.delete(0); 426 }) 427 } 428 } 429} 430 431 432@Entry 433@Component 434struct MapSample { 435 @State message: Map<number, string> = new Map([[0, "a"], [1, "b"], [3, "c"]]); 436 437 build() { 438 Row() { 439 Column() { 440 Child({ value: this.message }) 441 } 442 .width('100%') 443 } 444 .height('100%') 445 } 446} 447``` 448 449### Decorating Variables of the Set Type 450 451> **NOTE** 452> 453> Since API version 11, \@Link supports the Set type. 454 455In this example, the **message** variable is of the **Set\<number\>** type. When the button is clicked, the value of **message** changes, and the UI is re-rendered. 456 457```ts 458@Component 459struct Child { 460 @Link message: Set<number>; 461 462 build() { 463 Column() { 464 ForEach(Array.from(this.message.entries()), (item: [number, number]) => { 465 Text(`${item[0]}`).fontSize(30) 466 Divider() 467 }) 468 Button('init set').onClick(() => { 469 this.message = new Set([0, 1, 2, 3, 4]); 470 }) 471 Button('set new one').onClick(() => { 472 this.message.add(5); 473 }) 474 Button('clear').onClick(() => { 475 this.message.clear(); 476 }) 477 Button('delete the first one').onClick(() => { 478 this.message.delete(0); 479 }) 480 } 481 .width('100%') 482 } 483} 484 485 486@Entry 487@Component 488struct SetSample { 489 @State message: Set<number> = new Set([0, 1, 2, 3, 4]); 490 491 build() { 492 Row() { 493 Column() { 494 Child({ message: this.message }) 495 } 496 .width('100%') 497 } 498 .height('100%') 499 } 500} 501``` 502 503### Decorating Variables of the Date Type 504 505In this example, the **selectedDate** variable is of the Date type. After the button is clicked, the value of **selectedDate** changes, and the UI is re-rendered. 506 507```ts 508@Component 509struct DateComponent { 510 @Link selectedDate: Date; 511 512 build() { 513 Column() { 514 Button(`child increase the year by 1`) 515 .onClick(() => { 516 this.selectedDate.setFullYear(this.selectedDate.getFullYear() + 1); 517 }) 518 Button('child update the new date') 519 .margin(10) 520 .onClick(() => { 521 this.selectedDate = new Date('2023-09-09'); 522 }) 523 DatePicker({ 524 start: new Date('1970-1-1'), 525 end: new Date('2100-1-1'), 526 selected: this.selectedDate 527 }) 528 } 529 } 530} 531 532@Entry 533@Component 534struct ParentComponent { 535 @State parentSelectedDate: Date = new Date('2021-08-08'); 536 537 build() { 538 Column() { 539 Button('parent increase the month by 1') 540 .margin(10) 541 .onClick(() => { 542 this.parentSelectedDate.setMonth(this.parentSelectedDate.getMonth() + 1); 543 }) 544 Button('parent update the new date') 545 .margin(10) 546 .onClick(() => { 547 this.parentSelectedDate = new Date('2023-07-07'); 548 }) 549 DatePicker({ 550 start: new Date('1970-1-1'), 551 end: new Date('2100-1-1'), 552 selected: this.parentSelectedDate 553 }) 554 555 DateComponent({ selectedDate:this.parentSelectedDate }) 556 } 557 } 558} 559``` 560 561### Using the Two-Way Synchronization Mechanism to Change Local Variables 562 563Use [\@Watch](./arkts-watch.md) to change local variables during two-way synchronization. 564 565In the following example, the \@Watch callback on an \@Link variable modifies the @State decorated **memberMessage** variable, achieving variable synchronization between parent and child components. However, local modifications to the @State decorated **memberMessage** variable will not propagate changes back to the parent component. 566 567```ts 568@Entry 569@Component 570struct Parent { 571 @State sourceNumber: number = 0; 572 573 build() { 574 Column() { 575 Text(`sourceNumber of the parent component: ` + this.sourceNumber) 576 Child({ sourceNumber: this.sourceNumber }) 577 Button('Change sourceNumber in Parent Component') 578 .onClick(() => { 579 this.sourceNumber++; 580 }) 581 } 582 .width('100%') 583 .height('100%') 584 } 585} 586 587@Component 588struct Child { 589 @State memberMessage: string = 'Hello World'; 590 @Link @Watch('onSourceChange') sourceNumber: number; 591 592 onSourceChange() { 593 this.memberMessage = this.sourceNumber.toString(); 594 } 595 596 build() { 597 Column() { 598 Text(this.memberMessage) 599 Text(`sourceNumber of the child component: ` + this.sourceNumber.toString()) 600 Button('Change memberMessage in Child Component') 601 .onClick(() => { 602 this.memberMessage = 'Hello memberMessage'; 603 }) 604 } 605 } 606} 607``` 608 609## Union Type Support 610 611The \@Link decorator supports union types, including **undefined** and **null**. In the following example, the **name** variable is declared with type **string | undefined**. After the button in the parent **Index** component is clicked to modify either the value or type of **name**, the **Child** component will automatically update to reflect these changes. 612 613```ts 614@Component 615struct Child { 616 @Link name: string | undefined; 617 618 build() { 619 Column() { 620 621 Button('Child change name to Bob') 622 .onClick(() => { 623 this.name = "Bob"; 624 }) 625 626 Button('Child change name to undefined') 627 .onClick(() => { 628 this.name = undefined; 629 }) 630 631 }.width('100%') 632 } 633} 634 635@Entry 636@Component 637struct Index { 638 @State name: string | undefined = "mary"; 639 640 build() { 641 Column() { 642 Text(`The name is ${this.name}`).fontSize(30) 643 644 Child({ name: this.name }) 645 646 Button('Parents change name to Peter') 647 .onClick(() => { 648 this.name = "Peter"; 649 }) 650 651 Button('Parents change name to undefined') 652 .onClick(() => { 653 this.name = undefined; 654 }) 655 } 656 } 657} 658``` 659 660## Common Issues 661 662### Type Mismatch in \@Link Decorated Variables 663 664When \@Link is used to decorate state variables in child components, the variable type must exactly match its data source type. The data source must be a state variable decorated with \@State or other state decorators. 665 666**Incorrect Usage** 667 668```ts 669@Observed 670class Info { 671 public age: number = 0; 672 673 constructor(age: number) { 674 this.age = age; 675 } 676} 677 678@Component 679struct LinkChild { 680 @Link testNum: number; 681 682 build() { 683 Text(`LinkChild testNum ${this.testNum}`) 684 } 685} 686 687@Entry 688@Component 689struct Parent { 690 @State info: Info = new Info(1); 691 692 build() { 693 Column() { 694 Text(`Parent testNum ${this.info.age}`) 695 .onClick(() => { 696 this.info.age += 1; 697 }) 698 // The type of the @Link decorated variable must be the same as that of the @State decorated data source. 699 LinkChild({ testNum: this.info.age }) 700 } 701 } 702} 703``` 704 705In the example, the type of the \@Link decorated **testNum** variable and the initialization from the parent component **LinkChild({testNum:this.info.age})** are incorrect. The data source of \@Link must be a decorated state variable. The \@Link decorated variables must be of the same type as the data source, for example, \@Link: T and \@State: T. Therefore, **\@Link testNum: number** should be changed to **\@Link testNum: Info**, with initialization from the parent component as **LinkChild({testNum: this.info})**. 706 707**Correct Usage** 708 709```ts 710@Observed 711class Info { 712 public age: number = 0; 713 714 constructor(age: number) { 715 this.age = age; 716 } 717} 718 719@Component 720struct LinkChild { 721 @Link testNum: Info; 722 723 build() { 724 Text(`LinkChild testNum ${this.testNum?.age}`) 725 .onClick(() => { 726 this.testNum.age += 1; 727 }) 728 } 729} 730 731@Entry 732@Component 733struct Parent { 734 @State info: Info = new Info(1); 735 736 build() { 737 Column() { 738 Text(`Parent testNum ${this.info.age}`) 739 .onClick(() => { 740 this.info.age += 1; 741 }) 742 // The type of the @Link decorated variable must be the same as that of the @State decorated data source. 743 LinkChild({ testNum: this.info }) 744 } 745 } 746} 747``` 748 749### Using the a.b(this.object) Pattern Fails to Trigger UI Re-rendering 750 751In the **build** method, when a variable decorated with \@Link is of the object type and is called using the **a.b(this.object)** pattern, the **b** method receives the original object of **this.object**, and modifying its properties will not trigger UI re-rendering. In the following example, when the static method **Score.changeScore1** or **this.changeScore2** is used to change **this.score.value** in the **Child** component, the UI is not re-rendered. 752 753**Incorrect Usage** 754 755```ts 756class Score { 757 value: number; 758 constructor(value: number) { 759 this.value = value; 760 } 761 762 static changeScore1(score:Score) { 763 score.value += 1; 764 } 765} 766 767@Entry 768@Component 769struct Parent { 770 @State score: Score = new Score(1); 771 772 build() { 773 Column({space:8}) { 774 Text(`The value in Parent is ${this.score.value}.`) 775 .fontSize(30) 776 .fontColor(Color.Red) 777 Child({ score: this.score }) 778 } 779 .width('100%') 780 .height('100%') 781 } 782} 783 784@Component 785struct Child { 786 @Link score: Score; 787 788 changeScore2(score:Score) { 789 score.value += 2; 790 } 791 792 build() { 793 Column({space:8}) { 794 Text(`The value in Child is ${this.score.value}.`) 795 .fontSize(30) 796 Button(`changeScore1`) 797 .onClick(()=>{ 798 // Static method calls will not trigger UI re-rendering. 799 Score.changeScore1(this.score); 800 }) 801 Button(`changeScore2`) 802 .onClick(()=>{ 803 // Internal component method calls using this will not trigger UI re-rendering. 804 this.changeScore2(this.score); 805 }) 806 } 807 } 808} 809``` 810 811You can add a proxy for **this.score** to re-render the UI by assigning a value to the variable and then calling the variable. 812 813**Correct Usage** 814 815```ts 816class Score { 817 value: number; 818 constructor(value: number) { 819 this.value = value; 820 } 821 822 static changeScore1(score:Score) { 823 score.value += 1; 824 } 825} 826 827@Entry 828@Component 829struct Parent { 830 @State score: Score = new Score(1); 831 832 build() { 833 Column({space:8}) { 834 Text(`The value in Parent is ${this.score.value}.`) 835 .fontSize(30) 836 .fontColor(Color.Red) 837 Child({ score: this.score }) 838 } 839 .width('100%') 840 .height('100%') 841 } 842} 843 844@Component 845struct Child { 846 @Link score: Score; 847 848 changeScore2(score:Score) { 849 score.value += 2; 850 } 851 852 build() { 853 Column({space:8}) { 854 Text(`The value in Child is ${this.score.value}.`) 855 .fontSize(30) 856 Button(`changeScore1`) 857 .onClick(()=>{ 858 // Add a proxy by assigning a value. 859 let score1 = this.score; 860 Score.changeScore1(score1); 861 }) 862 Button(`changeScore2`) 863 .onClick(()=>{ 864 // Add a proxy by assigning a value. 865 let score2 = this.score; 866 this.changeScore2(score2); 867 }) 868 } 869 } 870} 871``` 872 873<!--no_check--> 874