当前位置: 首页 > news >正文

Compose 声明式编程 状态 数据传递模式

Compose 声明式编程 状态 & 数据传递模式

Compose 里"哪种 API 存哪种状态"很容易选错——选轻了状态被旋转吃掉,选重了在该用remember的地方架个 ViewModel。
这份文档把项目里已经在用的几种模式按"作用域 + 异步性"两条轴排一下,给出选型决策、样例代码和踩过的坑。


0. 一句话决策表

我要存的 / 做的用什么
按钮按下、对话框开关、tab 选中等纯视觉态remember { mutableStateOf(...) }
旋转 / 进后台要保住的 UI 状态rememberSaveable
由其他可观察状态算出来的派生值derivedStateOf
一次性异步拉取的结果(屏幕私有)produceState
监听某些 key 变化跑副作用LaunchedEffect(key)
点击事件里要启动协程rememberCoroutineScope
复杂状态机 / 跨重组 / 需要测试 / 需要分页ViewModel+StateFlow
多屏共享 / 活动级单例Activity 作用域ViewModel
沿组合树隐式传递(导航回调、当前用户身份)CompositionLocalLocalBack/LocalNavigationTo/LocalCurrentUserId
把多个 list 参数收成一个传给子 Composabledata class包装
让子 Composable 不关心数据形态,只渲染tabContent: @Composable () -> Unitslot lambda

1. 作用域 × 异步性 四象限

┌──────────────────────────┬──────────────────────────┐ │ Composition 内(短) │ ViewModel 内(长) │ ┌───────────────────┼──────────────────────────┼──────────────────────────┤ │ 同步 / 即时 │ remember / mutableStateOf│ ViewModel 普通字段 │ │ │ rememberSaveable │ │ ├───────────────────┼──────────────────────────┼──────────────────────────┤ │ 异步 / 协程 │ LaunchedEffect │ StateFlow + viewModelScope│ │ │ produceState │ .launch │ │ │ rememberCoroutineScope │ │ └───────────────────┴──────────────────────────┴──────────────────────────┘
  • 左侧生命周期是 “Composable 在屏 / 离屏” —— 旋转、Tab 切走 + 切回都会重建。
  • 右侧生命周期是 ViewModelStore —— 跟 Activity 走,旋转不丢,离开屏幕也保留(直到 ViewModelStore 清理)。

2. 各模式详解

2.1remember { mutableStateOf(...) }—— 最轻量的本地状态

varsheetOpenbyremember{mutableStateOf(false)}Button(onClick={sheetOpen=true}){Text("Open")}if(sheetOpen){BottomSheet(onDismiss={sheetOpen=false})}

适合:纯 UI 视觉状态(开关、动画 trigger、tab index 等);与数据层无关。

不适合

  • 想让旋转后还保留 → 用rememberSaveable
  • 想让多个 composable 共享 → 提升到父组件,或上 ViewModel。
  • 想存 List / 复杂对象 → 想清楚是不是该上 StateFlow。

经典陷阱:把 props 当 seed 写进 remember:

// ❌ 错的——props.followedByMe 变化后 isFollowing 不会更新varisFollowingbyremember{mutableStateOf(props.followedByMe)}// ✅ 加 key——props 变化时 remember 块重建,按新 props seedvarisFollowingbyremember(props.followedByMe){mutableStateOf(props.followedByMe)}

第二种写法在OtherScreenproduceState时承担过 follow 按钮的状态管理。


2.2rememberSaveable—— 旋转保活的本地状态

varisLandscapebyrememberSaveable{mutableStateOf(false)}

适合:旋转 / 进后台后还想保住的纯 UI 状态。

限制

  • 只能存Parcelable/Serializable/ 内置基本类型。自定义类要写Saver
  • 跨进程 kill 也能恢复(依赖 SavedInstanceState)。

反例 / 坑:用rememberSaveable存"一次性事件完成"flag(典型:“已经跳过页”)——见anti-pattern #1


2.3derivedStateOf—— 派生状态,避免抖动

valshouldLoadMorebyremember(pagerState){derivedStateOf{valtotal=state.items.size total>0&&pagerState.settledPage>=total-PRELOAD_AHEAD&&state.hasMore&&!state.isLoadingMore}}

关键性能特性:只有当内部读到的可观察状态计算出的结果发生变化,下游订阅者才会被通知。换句话说,pager 滑动每帧 offset 抖动不会让shouldLoadMore重新通知;只有 false→true / true→false 翻转才会。

适合

  • 监听多个 state 算出一个 boolean / 简化值。
  • LaunchedEffect
http://www.zskr.cn/news/1454872.html

相关文章:

  • 如何快速批量下载音乐同步歌词:面向音乐爱好者的完整指南
  • Arduino渐进式夏令时时钟:非阻塞算法与时间平滑过渡实践
  • 3步掌握缠论可视化:通达信插件终极指南
  • 工业视觉异常检测:PatchCore与EfficientAD原理、实战与调优
  • Windows安卓应用安装终极指南:告别模拟器,5分钟玩转APK安装器
  • 输入框自动记住常用词,点开就能搜历史、模糊匹配快速选
  • Circuit Playground 制作电子彩虹云朵帽:STEAM 亲子编程与手工指南
  • 计算机毕业设计之“暖医伴老行”老年智能医护小程序的设计与开发
  • Obsidian Border主题深度定制:技术架构解析与高效工作流优化
  • Diff Checker:3分钟掌握高效文本差异对比的终极解决方案
  • Douyin-Downloader:抖音内容批量下载的技术解决方案
  • 智慧职教刷课脚本:三分钟告别重复学习,解放你的宝贵时间
  • Relique:优质卡牌作为 RWA 资产上链的意义
  • 传统出汗越多排毒越好,编写程序根据心率,体温,出汗量,判断出汗类型,区分正常出汗与体虚盗汗。
  • 2026黔西州本地黄金回收铂金白银回收哪家强?TOP5 正规门店榜单 + 联系方式 - 中安检金银铂钻回收
  • Langflow完整使用指南:5个技巧快速掌握可视化AI工作流构建
  • 低烟无卤电缆品牌实力观察:多维视角下的行业代表性企业分析 - 速递信息
  • 控制器可靠性简介
  • 3个Windows Terminal启动目录配置技巧,让开发效率提升300%
  • 从数据孤岛到智能闭环,AI工具与会员系统打通的4层技术栈,92%企业卡在第2层
  • 从普刊到 SCI 全链路撰稿:Paperxie 期刊论文分层创作方案,打破科研发稿前期写作瓶颈
  • Elasticsearch Reindex 现已支持跨节点自动迁移:无需人工干预,不会丢失进度
  • Vue+Flask实现的火焰检测网页系统(含YOLOv5模型、前后端源码与部署脚本)
  • 2026深圳装修公司实力推荐榜|本土履约、施工透明、售后靠谱装企盘点 - 商业新知
  • Arduino继电器控制220V灯串:从安全电路到音乐灯光秀的完整指南
  • 2026实木家具直销选购白皮书:这5家口碑厂家值得收藏 - kio888
  • 2026年6月乐山贵金属回收权威门店排行 TOP5 黄金 + 铂金 + 白银回收 附电话地址 - 中业金奢再生回收中心
  • 分布式高可用抢票系统架构:如何构建可观测的Rust自动化购票平台
  • 基于Arduino与超声波传感器的自动旗帜挥舞装置:从原理到实践
  • Beyond Compare 5激活密钥生成器:3种方法实现永久授权