合理的状态管理 原创
一、减少不必要的深拷贝
在开发中如何需要父子组件进行值的传递,在不改变子组件中变量值的情况下使用@Prop状态变量会导致组件创建的耗时增加。
例如:
片段一
@Entry
@Component
struct Index {
@State student: Student = new Student("张三", 20)
build() {
Column() {
Text(`${this.student.name} :${this.student.age}`)
.onClick(() => {
this.student.age++
})
//子组件
ChildComponent({ student: this.student })
}
.height('100%')
.justifyContent(FlexAlign.Center)
.width('100%')
}
}
//子组件
@Component
struct ChildComponent {
@Prop student: Student
build() {
Text(`${this.student.name} :${this.student.age}`)
.margin({top:20})
}
}
class Student {
name: string = ""
age: number = 0
constructor(name: string, age: number) {
this.age = age
this.name = name
}
}
片段二
@Entry
@Component
struct Index {
@State student: Student = new Student("张三", 20)
build() {
Column() {
Text(`${this.student.name} :${this.student.age}`)
.onClick(() => {
this.student.age++
})
//子组件
ChildComponent({ student: this.student })
}
.height('100%')
.justifyContent(FlexAlign.Center)
.width('100%')
}
}
//子组件
@Component
struct ChildComponent {
@ObjectLink student: Student
build() {
Text(`${this.student.name} :${this.student.age}`)
.margin({top:20})
}
}
@Observed
class Student {
name: string = ""
age: number = 0
constructor(name: string, age: number) {
this.age = age
this.name = name
}
}
片段一和片段二区别是子组件中的变量student是由@Porp修饰还是由@ObjectLink修饰,实现效果是一样的,但是@Porp会导致装饰状态变量深拷贝,所以这种情况使用@ObjectLink是最优的选择。
二、控制状态变量的组件数
最好让每个状态变量关联的组件数量控制在 20 个以内。要是能精准把控状态变量关联的组件数,就可以减少那些没必要进行刷新的组件,进而提升组件的刷新效率。常常会出现这样的情况,开发者把同一个状态变量和多个同级组件的属性绑定在一起,一旦这个状态变量发生变化,那些组件就都会跟着做出同样的改变,而这在有些时候会导致组件出现不必要的刷新情况。要是组件比较复杂的话,还会对整体性能产生很大的影响呢。不过要是把这个状态变量绑定到这些同级组件的父组件上,需要刷新的组件数量就能减少了,刷新性能也就随之提高了。
三、控制复杂对象作为状态变量时的关联组件数
在将一个复杂对象定义为状态变量时,对其关联的组件数进行合理控制是十分必要的。由于存在这样一种情况,即当该复杂对象中的某一成员属性发生变化时,不管与之关联的组件是否直接使用了这一发生改变的属性,都会致使这些组件全部进行刷新。而这种 “冗余刷新” 现象往往会对性能产生负面影响,鉴于此,建议通过合理拆分该复杂对象的方式,来有效控制对象关联的组件数量,进而规避因 “冗余刷新” 带来的性能问题。
四、避免在for、while等循环逻辑中频繁读取状态变量
反例
@Entry
@Component
struct Index {
@State message: string = "Hello World"
build() {
Column() {
Button().onClick(() => {
for (let i = 0; i < 10; i++) {
console.log(this.message)
}
})
}
.height('100%')
.justifyContent(FlexAlign.Center)
.width('100%')
}
}
正例
@Entry
@Component
struct Index {
@State message: string = "Hello World"
build() {
Column() {
Button().onClick(() => {
let msg = this.message
for (let i = 0; i < 10; i++) {
console.log(msg)
}
})
}
.height('100%')
.justifyContent(FlexAlign.Center)
.width('100%')
}
}