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