1# Arkui Subsystem State Management Changelog
2
3
4# Support by @Prop for Object Behavior Changes
5
6## cl. Change from Shallow Copy to Deep Copy of Objects by @Prop
7
8**Change Impact**
9
10In API version 9, @Prop supports shallow copy of objects. The specific behavior is as follows:
11
12- Object type: shallow copy of all properties returned by **Object.keys(propObj)**. That is, only the outermost object is copied, and the property in the object points to the data source of the original parent component.
13- Array type: shallow copy of all array items. That is, only the outermost array is copied. Other behaviors are the same as those of the Object type.
14- The prototype of the object and array is copied.
15
16Since API version 10, @Prop supports deep copy of objects. The specific behavior is as follows:
17- Object type: deep copy of all properties returned by **Object.keys(propObj)**.
18- Array type: deep copy of all array items.
19- The prototype of the object and array is copied.
20
21**Adaptation Guide**
22
23The impact of the change on UI rendering mainly lies in @ObjectLink-related scenarios, because @ObjectLink functions as a proxy for its decorated object properties.
24
25The following shows an example:
26
27API version 9: If @Prop objArray in the PropClassArray component changes the property of ClassA or sets a new array item, @ObjectLink obj in ObjectLinkClassA created by the parent component StateClassAArray changes.
28
29The update is caused by the shallow copy from @State stateClassAArray in the parent component StateClassAArray to @Prop objArray in the child component PropClassAArray. The shallow copy copies only the reference of array items, and therefore the data source is changed. As @ObjectLink functions as a proxy for the properties of the data source, the update of @ObjectLink obj (constructed from the StateClassAArray component) in the ObjectLinkClassA component is triggered.
30
31API version 10: In the preceding scenario, the copy from @State stateClassAArray in the parent component StateClassAArray to @Prop objArray in the child component PropClassAArray is a deep copy. As the object of ClassA is completely copied, the data source is not changed, and the update of @ObjectLink obj (constructed from the StateClassAArray component) in the ObjectLinkClassA component is not triggered.
32
33
34![en-us_image_0000001588291546](figures/en-us_image_0000001588291546.png)
35
36
37
38```ts
39let nextId = 0;
40
41@Observed
42class ClassA  {
43  id : number;
44  a : number;
45  constructor(a : number = 0) {
46    this.id = nextId++;
47    this.a = a;
48  }
49}
50
51@Component
52struct ObjectLinkClassA {
53  @ObjectLink obj : ClassA;
54
55  build() {
56    Row() {
57      Text(`ObjectLink: obj: ${this.obj.a}`)
58        .height(100)
59        .onClick(() => {
60          this.obj.a += 1;
61          console.info(`ObjectLink onClick ClassA property changed to  ${this.obj.a}`)
62        })
63    }.border({width: 3, color: Color.Red})
64  }
65}
66
67@Component
68struct PropClassAArray {
69  @Prop objArray : Array<ClassA> = [];
70
71  build() {
72    Column() {
73      Text(`green box: @Prop : Array<ObjectClassA> item [0] + [1]`)
74      Row() {
75        ObjectLinkClassA({ obj:  this.objArray[0] })
76        Text("[0] Assign new ClassA")
77          .height(100)
78          .onClick(() => {
79            this.objArray[0] = new ClassA();
80            console.info(`PropClassAArray[0] onClick ClassA object assign ${this.objArray[0].a}`)
81          })
82        Text("Change ClassA property")
83          .height(100)
84          .onClick(() => {
85            this.objArray[0].a += 1;
86            console.info(`PropClassAArray[1] onClick ClassA property change  ${this.objArray[1].a}`)
87          })
88      }
89    }.border({width: 3, color: Color.Green})
90  }
91}
92
93@Entry
94@Component
95struct StateClassAArray {
96  @State stateClassAArray : Array<ClassA> = [ new ClassA(), new ClassA() ];
97
98  build() {
99    Column() {
100      Column() {
101        Text("Red box: @ObjectLink from @State array item[0]")
102        Row() {
103          ObjectLinkClassA({obj : this.stateClassAArray[0] })
104          Text("Assign new ClassA")
105            .height(100)
106            .onClick(() => {
107              this.stateClassAArray[0] = new ClassA();
108              console.info(`StateClassAArray[0] onClick ClassA object assign ${this.stateClassAArray[0].a}`)
109            })
110          Text("Change ClassA property")
111            .height(100)
112            .onClick(() => {
113              this.stateClassAArray[0].a += 1;
114              console.info(`StateClassAArray onClick stateClassAArray[0] changed to  ${this.stateClassAArray[0].a}`)
115            })
116        }
117
118      }.border({width: 3, color: Color.Blue})
119
120      Divider().height(5)
121
122      // Shallow copy in API version 9: Only the reference pointing to the source array item is copied, and the ClassA instance itself is not copied.
123      // Deep copy in API version 10: The this.stateClassAArray instance is completely copied, including its array items.
124      PropClassAArray({ objArray: this.stateClassAArray })
125    }
126  }
127}
128```
129