• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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![en-us_image_0000001502092556](figures/en-us_image_0000001502092556.png)
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![Video-link-UsageScenario-one](figures/Video-link-UsageScenario-one.gif)
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![Video-link-UsageScenario-two](figures/Video-link-UsageScenario-two.gif)
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