
引言
状态管理是HarmonyOS应用开发中的核心概念。本文将深入探讨ArkTS中的状态管理机制,包括:
- 组件状态管理
- 全局状态管理
- 状态同步策略
- 复杂状态场景处理
通过本文,你将掌握如何在实际项目中高效管理应用状态。
学习目标
完成本文后,你将能够:
- ✅ 理解组件状态管理
- ✅ 实现全局状态管理
- ✅ 处理状态同步
- ✅ 解决复杂状态场景
需求分析
状态管理场景
| 场景 | 描述 | 技术要点 |
|---|---|---|
| 组件状态 | 单个组件的状态 | @State、@Prop、@Link |
| 全局状态 | 跨组件共享状态 | 全局Store、事件总线 |
| 异步状态 | 异步数据加载 | Promise、async/await |
| 复杂状态 | 多层级状态嵌套 | 状态树、状态切片 |
状态管理方案对比与选型
常见状态管理方案
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| ArkTS内置状态 | 组件内状态、父子组件通信 | 轻量、简单、响应式更新 | 不支持跨页面共享 |
| 全局单例Store | 全局状态共享 | 集中管理、易于维护 | 需要手动处理订阅 |
| 事件总线 | 组件间解耦通信 | 解耦性好、灵活 | 难以追踪数据流 |
| 路由参数 | 页面间数据传递 | 简单直接 | 只适合少量数据 |
| 持久化存储 | 跨会话状态保持 | 数据持久化 | 性能开销、异步操作 |
方案选型建议
小型应用(单页面为主):
- 使用ArkTS内置状态即可满足需求
- 简单的全局状态可以用单例Store
中型应用(多页面、复杂交互):
- 组合使用:内置状态 + 全局Store + 事件总线
- 考虑使用状态切片管理不同业务模块
大型应用(复杂状态、多人协作):
- 需要更完善的状态管理方案
- 可考虑引入状态管理库或设计更完善的架构
状态管理架构设计原则
- 单一职责原则:每个状态只负责一个业务领域
- 最小化状态:只维护必要的状态,避免冗余
- 状态不可变性:状态更新通过替换而非修改
- 可预测性:状态变化应该是可追踪和可预测的
- 易于测试:状态管理逻辑应该易于单元测试
核心实现
步骤1: 组件状态管理
typescript
// 组件状态管理示例
@Entry
@Component
struct ComponentStateDemo {
// 本地状态 - 组件内部使用
@State count: number = 0;
@State isExpanded: boolean = false;
@State userInfo: UserInfo | null = null;
// 从父组件接收的状态 - 单向传递
@Prop title: string = '';
// 双向绑定状态 - 父子组件同步
@Link syncValue: number;
// 计算属性 - 根据其他状态计算
@Computed get total(): number {
return this.count * 2;
}
// 异步加载数据
async aboutToAppear() {
this.userInfo = await this.fetchUserInfo();
}
async fetchUserInfo(): Promise<UserInfo> {
// 模拟网络请求
return new Promise(resolve => {
setTimeout(() => {
resolve({
id: '1',
name: '张三',
avatar: '',
level: 5
});
}, 1000);
});
}
build() {
Column({ space: 12 }) {
// 使用@Prop
Text(this.title)
.fontSize(20)
.fontWeight(FontWeight.Bold)
// 使用@State
Row({ space: 12 }) {
Button('+')
.onClick(() => this.count++)
Text(`Count: ${this.count}`)
Button('-')
.onClick(() => this.count--)
}
// 使用@Computed
Text(`Total: ${this.total}`)
.fontSize(16)
.fontColor('#999999')
// 使用@Link
Row({ space: 12 }) {
Text('同步值:')
TextInput({ placeholder: '输入数字' })
.type(InputType.Number)
.onChange((value: string) => {
this.syncValue = parseInt(value) || 0;
})
}
// 条件渲染
if (this.userInfo) {
Card() {
Row({ space: 12 }) {
Circle()
.width(40)
.height(40)
.fillColor('#E8F5E9')
Column({ space: 4 }) {
Text(this.userInfo.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
Text(`等级: ${this.userInfo.level}`)
.fontSize(12)
.fontColor('#999999')
}
}
.padding(12)
}
} else {
// 加载状态
LoadingProgress()
.width(40)
.height(40)
}
// 展开/收起
Button(this.isExpanded ? '收起' : '展开')
.onClick(() => {
this.isExpanded = !this.isExpanded;
})
if (this.isExpanded) {
Text('展开的内容...')
.fontSize(14)
.fontColor('#666666')
.padding(12)
.backgroundColor('#FFFFFF')
.borderRadius(8)
}
}
.width('100%')
.height('100%')
.padding(16)
.justifyContent(FlexAlign.Center)
.backgroundColor('#F8F7F2')
}
}
interface UserInfo {
id: string;
name: string;
avatar: string;
level: number;
}
设计要点:
- @State 本地状态
- @Prop 单向传递
- @Link 双向绑定
- @Computed 计算属性
- 条件渲染
步骤2: 全局状态管理
typescript
// 全局状态管理示例
class GlobalStore {
// 单例实例
private static instance: GlobalStore;
// 用户状态
private userState: UserState = {
isLoggedIn: false,
userInfo: null,
token: ''
};
// 学习状态
private learningState: LearningState = {
totalDays: 0,
articlesRead: 0,
score: 0
};
// 监听者列表
private listeners: Map<string, Set<() => void>> = new Map();
private constructor() {}
static getInstance(): GlobalStore {
if (!GlobalStore.instance) {
GlobalStore.instance = new GlobalStore();
}
return GlobalStore.instance;
}
// 用户状态操作
getUserState(): UserState {
return { ...this.userState };
}
setUserState(state: Partial<UserState>): void {
this.userState = { ...this.userState, ...state };
this.notify('user');
}
// 学习状态操作
getLearningState(): LearningState {
return { ...this.learningState };
}
updateLearningState(state: Partial<LearningState>): void {
this.learningState = { ...this.learningState, ...state };
this.notify('learning');
}
// 订阅状态变化
subscribe(key: string, listener: () => void): void {
if (!this.listeners.has(key)) {
this.listeners.set(key, new Set());
}
this.listeners.get(key)?.add(listener);
}
// 取消订阅
unsubscribe(key: string, listener: () => void): void {
this.listeners.get(key)?.delete(listener);
}
// 通知监听者
private notify(key: string): void {
this.listeners.get(key)?.forEach(listener => listener());
}
// 清除所有状态
clear(): void {
this.userState = {
isLoggedIn: false,
userInfo: null,
token: ''
};
this.notify('user');
}
}
interface UserState {
isLoggedIn: boolean;
userInfo: UserInfo | null;
token: string;
}
interface LearningState {
totalDays: number;
articlesRead: number;
score: number;
}
interface UserInfo {
id: string;
name: string;
avatar: string;
}
// 创建全局实例
export const globalStore = GlobalStore.getInstance();
// 在组件中使用全局状态
@Entry
@Component
struct GlobalStateDemo {
@State userState: UserState = globalStore.getUserState();
@State learningState: LearningState = globalStore.getLearningState();
aboutToAppear() {
// 订阅用户状态变化
globalStore.subscribe('user', () => {
this.userState = globalStore.getUserState();
});
// 订阅学习状态变化
globalStore.subscribe('learning', () => {
this.learningState = globalStore.getLearningState();
});
}
aboutToDisappear() {
// 取消订阅
globalStore.unsubscribe('user', this.handleUserChange);
globalStore.unsubscribe('learning', this.handleLearningChange);
}
handleUserChange = () => {
this.userState = globalStore.getUserState();
}
handleLearningChange = () => {
this.learningState = globalStore.getLearningState();
}
onLogin() {
globalStore.setUserState({
isLoggedIn: true,
userInfo: {
id: '1',
name: '张三',
avatar: ''
},
token: 'mock_token'
});
}
updateScore() {
globalStore.updateLearningState({
score: this.learningState.score + 100
});
}
build() {
Column({ space: 16 }) {
if (this.userState.isLoggedIn) {
Text(`欢迎, ${this.userState.userInfo?.name}`)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Button('更新积分')
.onClick(() => this.updateScore())
} else {
Button('登录')
.onClick(() => this.onLogin())
}
Text(`学习天数: ${this.learningState.totalDays}`)
Text(`阅读文章: ${this.learningState.articlesRead}`)
Text(`积分: ${this.learningState.score}`)
}
.width('100%')
.height('100%')
.padding(16)
.justifyContent(FlexAlign.Center)
.backgroundColor('#F8F7F2')
}
}
设计要点:
- 单例模式
- 状态订阅机制
- 状态变更通知
步骤3: 状态同步策略
typescript
// 状态同步策略示例
/**
* 策略1: 事件总线模式
* 通过事件发布/订阅实现组件间通信
*/
class EventBus {
private listeners: Map<string, Set<(...args: any[]) => void>> = new Map();
emit(event: string, ...args: any[]): void {
this.listeners.get(event)?.forEach(listener => listener(...args));
}
on(event: string, listener: (...args: any[]) => void): void {
if (!this.listeners.has(event)) {
this.listeners.set(event, new Set());
}
this.listeners.get(event)?.add(listener);
}
off(event: string, listener: (...args: any[]) => void): void {
this.listeners.get(event)?.delete(listener);
}
}
const eventBus = new EventBus();
// 使用事件总线
@Entry
@Component
struct EventBusDemo {
@State message: string = '';
aboutToAppear() {
// 订阅事件
eventBus.on('message_update', (msg: string) => {
this.message = msg;
});
}
aboutToDisappear() {
// 取消订阅
eventBus.off('message_update', this.handleMessageUpdate);
}
handleMessageUpdate = (msg: string) => {
this.message = msg;
}
sendMessage() {
// 发布事件
eventBus.emit('message_update', 'Hello from EventBus!');
}
build() {
Column({ space: 16 }) {
Text(this.message)
.fontSize(18)
Button('发送消息')
.onClick(() => this.sendMessage())
}
.width('100%')
.height('100%')
.padding(16)
.justifyContent(FlexAlign.Center)
}
}
/**
* 策略2: 路由参数传递
* 通过路由跳转传递状态
*/
@Entry
@Component
struct RouterParamsDemo {
goToDetail() {
// 传递参数
router.pushUrl({
url: 'pages/Detail',
params: {
id: '1',
name: '立春',
type: 'solar_term'
}
});
}
build() {
Button('跳转到详情页')
.onClick(() => this.goToDetail())
}
}
// 接收参数的页面
@Entry
@Component
struct DetailPage {
@State params: Record<string, any> = {};
aboutToAppear() {
// 获取路由参数
this.params = router.getParams() || {};
}
build() {
Column({ space: 8 }) {
Text(`ID: ${this.params.id}`)
Text(`名称: ${this.params.name}`)
Text(`类型: ${this.params.type}`)
}
.width('100%')
.height('100%')
.padding(16)
.justifyContent(FlexAlign.Center)
}
}
/**
* 策略3: 持久化存储
* 通过本地存储同步状态
*/
@Entry
@Component
struct StorageSyncDemo {
@State count: number = 0;
aboutToAppear() {
// 从存储读取
storage.get('count', '0').then(value => {
this.count = parseInt(value);
});
}
onIncrement() {
this.count++;
// 保存到存储
storage.set('count', this.count.toString());
}
build() {
Column({ space: 16 }) {
Text(`Count: ${this.count}`)
.fontSize(20)
Button('+')
.onClick(() => this.onIncrement())
}
.width('100%')
.height('100%')
.padding(16)
.justifyContent(FlexAlign.Center)
}
}
// Mock storage
const storage = {
async get(key: string, defaultValue: string): Promise<string> {
return defaultValue;
},
async set(key: string, value: string): Promise<void> {}
};
设计要点:
- 事件总线模式
- 路由参数传递
- 持久化存储同步
步骤4: 复杂状态场景处理
typescript
// 复杂状态场景示例
/**
* 场景1: 表单状态管理
*/
@Entry
@Component
struct FormStateDemo {
@State formData: FormData = {
username: '',
email: '',
password: '',
rememberMe: false
};
@State errors: FormErrors = {};
validateForm(): boolean {
this.errors = {};
if (!this.formData.username.trim()) {
this.errors.username = '请输入用户名';
}
if (!this.formData.email.trim()) {
this.errors.email = '请输入邮箱';
} else if (!this.isValidEmail(this.formData.email)) {
this.errors.email = '请输入有效的邮箱地址';
}
if (!this.formData.password) {
this.errors.password = '请输入密码';
} else if (this.formData.password.length < 6) {
this.errors.password = '密码长度至少6位';
}
return Object.keys(this.errors).length === 0;
}
isValidEmail(email: string): boolean {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
onSubmit() {
if (this.validateForm()) {
// 提交表单
console.log('表单验证通过:', this.formData);
}
}
build() {
Column({ space: 12 }) {
// 用户名输入
Column({ space: 4 }) {
TextInput({ placeholder: '用户名' })
.onChange((value: string) => {
this.formData.username = value;
if (this.errors.username) {
delete this.errors.username;
}
})
if (this.errors.username) {
Text(this.errors.username)
.fontSize(12)
.fontColor('#FF5252')
}
}
// 邮箱输入
Column({ space: 4 }) {
TextInput({ placeholder: '邮箱' })
.onChange((value: string) => {
this.formData.email = value;
if (this.errors.email) {
delete this.errors.email;
}
})
if (this.errors.email) {
Text(this.errors.email)
.fontSize(12)
.fontColor('#FF5252')
}
}
// 密码输入
Column({ space: 4 }) {
TextInput({ placeholder: '密码' })
.type(InputType.Password)
.onChange((value: string) => {
this.formData.password = value;
if (this.errors.password) {
delete this.errors.password;
}
})
if (this.errors.password) {
Text(this.errors.password)
.fontSize(12)
.fontColor('#FF5252')
}
}
// 记住我
Row({ space: 8 }) {
Switch({ selected: this.formData.rememberMe })
.onChange((isOn: boolean) => {
this.formData.rememberMe = isOn;
})
Text('记住我')
.fontSize(14)
.fontColor('#666666')
}
Button('提交')
.width('100%')
.height(48)
.backgroundColor('#4A9B6D')
.fontColor('#FFFFFF')
.borderRadius(24)
.onClick(() => this.onSubmit())
}
.width('92%')
.height('100%')
.padding(16)
.justifyContent(FlexAlign.Center)
.backgroundColor('#F8F7F2')
}
}
interface FormData {
username: string;
email: string;
password: string;
rememberMe: boolean;
}
interface FormErrors {
username?: string;
email?: string;
password?: string;
}
/**
* 场景2: 列表状态管理
*/
@Entry
@Component
struct ListStateDemo {
@State items: ListItem[] = [];
@State isLoading: boolean = false;
@State hasMore: boolean = true;
@State page: number = 1;
async aboutToAppear() {
await this.loadData();
}
async loadData() {
this.isLoading = true;
// 模拟网络请求
await new Promise(resolve => setTimeout(resolve, 1000));
// 模拟数据
const newItems: ListItem[] = [
{ id: `${this.page}-1`, title: `项目 ${this.page}-1` },
{ id: `${this.page}-2`, title: `项目 ${this.page}-2` },
{ id: `${this.page}-3`, title: `项目 ${this.page}-3` }
];
this.items = [...this.items, ...newItems];
this.isLoading = false;
// 模拟分页结束
if (this.page >= 5) {
this.hasMore = false;
}
}
onLoadMore() {
if (!this.isLoading && this.hasMore) {
this.page++;
this.loadData();
}
}
onRefresh() {
this.page = 1;
this.items = [];
this.hasMore = true;
this.loadData();
}
build() {
List({ space: 8, initialIndex: 0 }) {
// 下拉刷新
ListItem() {
Refresh({ refreshing: this.isLoading, onRefresh: () => this.onRefresh() }) {
// 刷新内容
}
}
// 列表项
ForEach(this.items, (item: ListItem) => {
ListItem() {
Text(item.title)
.fontSize(16)
.fontColor('#333333')
.width('100%')
.height(48)
.padding({ left: 16 })
.backgroundColor('#FFFFFF')
.borderRadius(8)
.justifyContent(FlexAlign.Center)
}
}, (item: ListItem) => item.id)
// 加载更多
if (this.hasMore) {
ListItem() {
Row({ space: 8 }) {
if (this.isLoading) {
LoadingProgress().width(20).height(20)
Text('加载中...')
} else {
Text('点击加载更多')
}
}
.width('100%')
.height(48)
.justifyContent(FlexAlign.Center)
.onClick(() => this.onLoadMore())
}
} else {
ListItem() {
Text('没有更多数据')
.fontSize(14)
.fontColor('#999999')
.width('100%')
.height(48)
.justifyContent(FlexAlign.Center)
}
}
}
.width('92%')
.height('100%')
.padding({ top: 16 })
}
}
interface ListItem {
id: string;
title: string;
}
设计要点:
- 表单状态管理
- 列表分页状态
- 下拉刷新和加载更多
实际应用场景
场景1: 用户认证状态管理
typescript
// 用户认证状态管理
class AuthStore {
private static instance: AuthStore;
private user: User | null = null;
private token: string = '';
private isLoggedIn: boolean = false;
private listeners: Set<() => void> = new Set();
private constructor() {}
static getInstance(): AuthStore {
if (!AuthStore.instance) {
AuthStore.instance = new AuthStore();
}
return AuthStore.instance;
}
// 登录
async login(credentials: LoginCredentials): Promise<void> {
// 调用登录API
// const response = await AuthApi.login(credentials);
// 模拟登录成功
this.user = {
id: '1',
name: '张三',
email: 'zhangsan@example.com',
avatar: ''
};
this.token = 'mock_jwt_token';
this.isLoggedIn = true;
// 保存到持久化存储
await secureStorage.setObject('user', this.user);
await secureStorage.set('token', this.token);
this.notifyListeners();
}
// 登出
async logout(): Promise<void> {
this.user = null;
this.token = '';
this.isLoggedIn = false;
// 清除持久化存储
await secureStorage.remove('user');
await secureStorage.remove('token');
this.notifyListeners();
}
// 自动登录
async autoLogin(): Promise<boolean> {
const savedUser = await secureStorage.getObject<User>('user');
const savedToken = await secureStorage.get('token');
if (savedUser && savedToken) {
this.user = savedUser;
this.token = savedToken;
this.isLoggedIn = true;
this.notifyListeners();
return true;
}
return false;
}
// 获取用户信息
getUser(): User | null {
return this.user;
}
// 获取Token
getToken(): string {
return this.token;
}
// 是否登录
getIsLoggedIn(): boolean {
return this.isLoggedIn;
}
// 订阅状态变化
subscribe(listener: () => void): void {
this.listeners.add(listener);
}
// 取消订阅
unsubscribe(listener: () => void): void {
this.listeners.delete(listener);
}
// 通知监听者
private notifyListeners(): void {
this.listeners.forEach(listener => listener());
}
}
interface User {
id: string;
name: string;
email: string;
avatar: string;
}
interface LoginCredentials {
email: string;
password: string;
}
// Mock secureStorage
const secureStorage = {
async setObject(key: string, value: any): Promise<void> {},
async getObject<T>(key: string): Promise<T | null> { return null; },
async set(key: string, value: string): Promise<void> {},
async get(key: string): Promise<string> { return ''; },
async remove(key: string): Promise<void> {}
};
// 导出实例
export const authStore = AuthStore.getInstance();
场景2: 购物车状态管理
typescript
// 购物车状态管理
class CartStore {
private static instance: CartStore;
private items: CartItem[] = [];
private listeners: Set<() => void> = new Set();
private constructor() {}
static getInstance(): CartStore {
if (!CartStore.instance) {
CartStore.instance = new CartStore();
}
return CartStore.instance;
}
// 添加商品
addItem(item: CartItem): void {
const existingIndex = this.items.findIndex(i => i.id === item.id);
if (existingIndex >= 0) {
// 更新数量
this.items[existingIndex].quantity += item.quantity;
} else {
// 添加新商品
this.items.push({ ...item });
}
this.notifyListeners();
this.persist();
}
// 更新商品数量
updateQuantity(id: string, quantity: number): void {
const index = this.items.findIndex(i => i.id === id);
if (index >= 0) {
if (quantity <= 0) {
this.removeItem(id);
} else {
this.items[index].quantity = quantity;
this.notifyListeners();
this.persist();
}
}
}
// 删除商品
removeItem(id: string): void {
this.items = this.items.filter(i => i.id !== id);
this.notifyListeners();
this.persist();
}
// 清空购物车
clear(): void {
this.items = [];
this.notifyListeners();
this.persist();
}
// 获取购物车列表
getItems(): CartItem[] {
return [...this.items];
}
// 获取购物车数量
getTotalQuantity(): number {
return this.items.reduce((sum, item) => sum + item.quantity, 0);
}
// 获取购物车总价
getTotalPrice(): number {
return this.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
// 从持久化存储加载
async load(): Promise<void> {
const saved = await storage.get('cart', '');
if (saved) {
this.items = JSON.parse(saved);
this.notifyListeners();
}
}
// 持久化保存
private async persist(): Promise<void> {
await storage.set('cart', JSON.stringify(this.items));
}
// 订阅
subscribe(listener: () => void): void {
this.listeners.add(listener);
}
// 取消订阅
unsubscribe(listener: () => void): void {
this.listeners.delete(listener);
}
// 通知
private notifyListeners(): void {
this.listeners.forEach(listener => listener());
}
}
interface CartItem {
id: string;
name: string;
price: number;
quantity: number;
image?: string;
}
// Mock storage
const storage = {
async get(key: string, defaultValue: string): Promise<string> { return defaultValue; },
async set(key: string, value: string): Promise<void> {}
};
// 导出实例
export const cartStore = CartStore.getInstance();
常见问题与解决方案
问题1: 状态更新不触发UI刷新
现象: 修改状态后UI没有更新
原因:
- 对象/数组直接修改而不是替换
- 使用了不可变数据的错误方式
解决方案:
typescript
// 错误方式 - 直接修改数组
this.items.push(newItem); // UI不会刷新
// 正确方式 - 创建新数组
this.items = [...this.items, newItem]; // UI会刷新
// 错误方式 - 直接修改对象属性
this.user.name = '新名字'; // UI不会刷新
// 正确方式 - 创建新对象
this.user = { ...this.user, name: '新名字' }; // UI会刷新
问题2: 状态订阅导致内存泄漏
现象: 页面销毁后订阅仍在执行
解决方案:
typescript
@Entry
@Component
struct SafeSubscriptionPage {
private unsubscribeUser?: () => void;
private unsubscribeCart?: () => void;
aboutToAppear() {
// 订阅用户状态
this.unsubscribeUser = globalStore.subscribe('user', () => {
// 处理状态变化
});
// 订阅购物车状态
this.unsubscribeCart = cartStore.subscribe(() => {
// 处理状态变化
});
}
aboutToDisappear() {
// 取消订阅
if (this.unsubscribeUser) {
this.unsubscribeUser();
}
if (this.unsubscribeCart) {
this.unsubscribeCart();
}
}
build() {
// 页面内容
}
}
问题3: 异步操作导致状态不一致
现象: 多个异步操作同时修改状态导致数据混乱
解决方案:
typescript
// 使用状态锁防止并发问题
class AsyncSafeStore {
private isUpdating: boolean = false;
async updateData(newData: any): Promise<void> {
// 如果正在更新,等待完成
while (this.isUpdating) {
await new Promise(resolve => setTimeout(resolve, 50));
}
this.isUpdating = true;
try {
// 执行更新操作
await this.performUpdate(newData);
} finally {
this.isUpdating = false;
}
}
private async performUpdate(data: any): Promise<void> {
// 实际更新逻辑
}
}
问题4: 状态数据过大导致性能问题
现象: 状态数据太多导致UI渲染变慢
解决方案:
typescript
// 使用状态切片
class SlicedStore {
// 用户状态
private userSlice = new UserSlice();
// 学习状态
private learningSlice = new LearningSlice();
// 获取状态切片
getUserSlice(): UserSlice {
return this.userSlice;
}
getLearningSlice(): LearningSlice {
return this.learningSlice;
}
}
class UserSlice {
private user: User | null = null;
private listeners: Set<() => void> = new Set();
setUser(user: User | null): void {
this.user = user;
this.notify();
}
getUser(): User | null {
return this.user;
}
subscribe(listener: () => void): () => void {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
}
private notify(): void {
this.listeners.forEach(listener => listener());
}
}
class LearningSlice {
private stats: LearningStats = { totalDays: 0, score: 0 };
private listeners: Set<() => void> = new Set();
updateStats(stats: Partial<LearningStats>): void {
this.stats = { ...this.stats, ...stats };
this.notify();
}
getStats(): LearningStats {
return { ...this.stats };
}
subscribe(listener: () => void): () => void {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
}
private notify(): void {
this.listeners.forEach(listener => listener());
}
}
interface LearningStats {
totalDays: number;
score: number;
}
interface User {
id: string;
name: string;
}
性能优化策略
策略1: 状态懒加载
typescript
// 只在需要时加载状态
class LazyStore {
private data: any = null;
private isLoaded: boolean = false;
async getData(): Promise<any> {
if (this.isLoaded) {
return this.data;
}
// 懒加载数据
this.data = await this.loadData();
this.isLoaded = true;
return this.data;
}
private async loadData(): Promise<any> {
// 从API或存储加载数据
return {};
}
// 重置加载状态
reset(): void {
this.isLoaded = false;
this.data = null;
}
}
策略2: 状态变更防抖
typescript
// 合并频繁的状态更新
class DebouncedStore {
private debounceTimer: number | null = null;
private pendingUpdates: Array<() => void> = [];
scheduleUpdate(update: () => void): void {
this.pendingUpdates.push(update);
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
}
this.debounceTimer = setTimeout(() => {
this.applyUpdates();
}, 100); // 100ms防抖
}
private applyUpdates(): void {
// 批量应用所有待更新
this.pendingUpdates.forEach(update => update());
this.pendingUpdates = [];
this.debounceTimer = null;
}
}
本章小结
核心知识点
本文完成了状态管理实战的深度学习:
1. 状态管理方案对比
- ArkTS内置状态 vs 全局Store vs 事件总线
- 方案选型建议
2. 组件状态管理
- @State、@Prop、@Link、@Computed的正确使用
- 状态更新的正确方式(不可变性)
3. 全局状态管理
- 单例模式实现
- 订阅/通知机制
- 状态切片设计
4. 实际应用场景
- 用户认证状态管理
- 购物车状态管理
5. 常见问题解决方案
- 状态更新不触发UI刷新
- 订阅导致内存泄漏
- 异步操作导致状态不一致
- 状态数据过大
6. 性能优化策略
- 状态懒加载
- 状态变更防抖
下一步预告
状态管理实战已经完成!在下一篇文章中,我们将学习:
- 数据模型设计
- 数据结构定义
- 数据验证
- 数据转换