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