ArkTS 状态管理三个坑:@State、@StorageLink 与 @Builder 的正确用法
一、引子
最近在鸿蒙开发实践中心连着做了几个端侧小应用:喝水记录、番茄钟、记忆翻牌。功能都不复杂,真正花时间的反而是状态管理。ArkTS 的声明式 UI 看起来和 React 很像,但装饰器的规则更细,稍不注意就会出现“数据变了界面不动”的问题。这篇把三个最常踩的坑整理出来,附上我自己验证过的写法。
二、坑一:@State 修饰对象,改属性不一定刷新
@State 只保证“这个引用被替换时”触发刷新。如果你把对象整体重新赋值,界面会更新;但直接改内部字段,框架无法感知。正确做法有两种:一是重新构造一个新对象再赋给 @State,保持不可变;二是对象内部字段也用 @Observed / @ObjectLink 做深度观察,适合嵌套层级较深的场景。我在喝水记录里最初就是直接改 cups.count,界面纹丝不动,改成整体替换之后才恢复正常。
三、坑二:@StorageLink 不是全局状态收纳箱
跨页面共享状态,最省事的是 AppStorage 配合 @StorageLink。但要注意它和 @State 的优先级:同时声明时以 @StorageLink 为准,@State 的初值会被忽略。另一个容易忽略的点是类型,AppStorage 里存的是运行时值,读出来要自己保证类型一致,否则会出现“取到 undefined 但页面不报错”的情况。我的建议是给 key 统一定义常量,读写都走同一份常量,避免字符串拼错这种低级问题。
四、坑三:@Builder 复用时要传参,别捕获
@Builder 抽公共 UI 很好用,但如果函数内部直接引用了外层组件的状态变量,复用之后不会跟随新的状态刷新。解决办法是通过参数把值传进去,并且用按值传递的对象字面量形式,这样每次重建都会拿到最新值。记忆翻牌的卡面渲染就是靠这个方式,做到一份 Builder 服务所有卡片。
五、持久化怎么分工
运行时共享用 AppStorage,落盘用 Preferences。两者职责不要混:AppStorage 是内存态,进程结束就没了;Preferences 是异步 IO,适合存少量键值,比如设置项和最近一次进度。启动时先从 Preferences 读出来灌进 AppStorage,退出前再写回,这样页面里只面对一套状态,逻辑会清爽很多。
六、小结
总结成三句话:改对象要换引用,跨页共享走 AppStorage 并统一 key,@Builder 靠参数而不是闭包。把这三点守住,ArkTS 的状态问题基本能少一大半。后面准备再写一篇云端实践里编译打包的踩坑记录。
- 点赞
- 收藏
- 关注作者
评论(0)