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