第5章:数据驱动UI
状态管理
1. 状态管理概述
在ArkTS中,状态管理是构建动态UI的核心机制。状态(State)是指组件在运行期间可能发生变化的数据,当状态改变时,UI会自动更新以反映最新的数据状态。ArkTS提供了多种状态管理方案,适用于不同规模的应用程序。
2. 组件级状态管理
@State装饰器
@Entry
@Component
struct CounterComponent {
@State count: number = 0 // 组件私有状态
build() {
Column() {
Text(`Count: ${this.count}`)
.fontSize(30)
Button('+1')
.onClick(() => {
this.count++ // 状态变更触发UI更新
})
}
}
}
- 特点:状态变化仅影响当前组件及其子组件
- 适用场景:简单的局部状态管理
@Prop和@Link装饰器
@Prop:父组件向子组件传递单向数据@Link:建立父子组件间的双向绑定
3. 应用级状态管理
@Observed和@ObjectLink
@Observed
class User {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
@Component
struct UserProfile {
@ObjectLink user: User
build() {
Column() {
Text(`Name: ${this.user.name}`)
Text(`Age: ${this.user.age}`)
}
}
}
AppStorage全局状态
// 存储全局状态
AppStorage.SetOrCreate('theme', 'light')
// 组件中使用
@StorageProp('theme') theme: string = 'light'
@StorageLink('theme') themeLink: string = 'light'
4. 状态管理最佳实践
- 状态提升原则:将共享状态提升到最近的共同祖先组件
- 单一数据源:确保每个状态只存在一个唯一数据源
- 不可变数据:使用展开运算符或深拷贝来更新状态
- 状态拆分:将复杂状态拆分为多个简单状态
5. 状态管理方案对比
| 方案 | 作用范围 | 数据流向 | 适用场景 |
|---|---|---|---|
| @State | 组件内 | 组件内部 | 私有状态 |
| @Prop | 父子组件 | 父→子 | 单向数据传递 |
| @Link | 父子组件 | 双向绑定 | 需要双向同步 |
| @ObjectLink | 任意组件 | 观察对象变化 | 复杂对象状态 |
| AppStorage | 全局 | 任意方向 | 全局共享状态 |
6. 实战示例:购物车状态管理
// 定义状态模型
@Observed
class CartItem {
id: string
name: string
quantity: number
// ...
}
// 购物车状态管理
class CartStore {
@State items: CartItem[] = []
addItem(item: CartItem) {
this.items = [...this.items, item]
}
removeItem(id: string) {
this.items = this.items.filter(item => item.id !== id)
}
}
// 在组件中使用
@Entry
@Component
struct ShoppingCart {
private cart = new CartStore()
build() {
List() {
ForEach(this.cart.items, item => {
ListItem() {
CartItemView({ item })
}
})
}
}
}
7. 常见问题与解决方案
状态更新不触发UI刷新:
- 确保使用响应式装饰器(@State, @Observed等)
- 对于对象/数组,确保创建新引用而非直接修改
状态管理混乱:
- 遵循"单向数据流"原则
- 使用自定义Hook或Store类集中管理复杂状态
性能问题:
- 避免在高层组件管理过多状态
- 使用@StateLocal装饰器处理不涉及UI的状态
