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 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