一、remember 家族概览

remember 相关 API
├── remember()                    // 基础:重组后保持值
├── remember(key)                 // 带键:key变化时重新计算
├── rememberSaveable()           // 配置变更后保持
├── rememberCoroutineScope()     // 记住协程作用域
├── rememberUpdatedState()       // 记住最新值(用于副作用)
├── remember { mutableStateOf() } // 记住状态(最常用组合)
└── derivedStateOf()             // 记住派生状态(相关但独立)
API 作用 生命周期 适用场景 示例
remember() 存储值 重组后保持 普通状态、对象缓存 val data = remember { loadData() }
remember(key) 条件存储 key变化时刷新 依赖外部参数的计算 val user = remember(userId) { loadUser(userId) }
rememberSaveable() 持久化存储 配置变更后保持 表单输入、UI状态 var text by rememberSaveable { mutableStateOf("") }
rememberCoroutineScope() 协程作用域 跟随组合 在点击事件中启动协程 val scope = rememberCoroutineScope()
rememberUpdatedState() 最新值引用 始终更新 副作用中捕获最新回调 val callback by rememberUpdatedState(onClick)
derivedStateOf() 派生状态 依赖变化时 计算属性 val isValid by remember { derivedStateOf { text.length > 3 } }

二、特别说明

remember

var count by remember { mutableStateOf(0) }
    var text by remember { mutableStateOf("") }

    // ❌ 问题:每次重组都重新计算
    val isEven = count % 2 == 0  // 即使 count 没变也会计算

    // ❌ 问题:用 remember 但依赖不对
    val isOdd = remember { count % 2 != 0 }  // count 变化时不会更新!

rememberSaveable

  • 什么是配置变更
    "任何导致 Activity 重建的场景都是配置变更,都需要 rememberSaveable 来保持用户状态"

配置变更包括但不限于:

类型 示例 是否需要 rememberSaveable
屏幕方向 旋转手机 ✅ 是
语言区域 切换中英文 ✅ 是
深色模式 开启夜间主题 ✅ 是
字体大小 调整系统字体 ✅ 是
屏幕尺寸 进入分屏 ✅ 是
折叠状态 折叠屏展开 ✅ 是
键盘连接 外接键盘 ✅ 是
进程杀死 系统回收内存 ✅ 是
  • 能存什么?怎么存?

1. 基本类型 - 自动存

kotlin

var count by rememberSaveable { mutableIntStateOf(0) }
var text by rememberSaveable { mutableStateOf("") }
var flag by rememberSaveable { mutableStateOf(false) }

2. 可打包对象 - @Parcelize

kotlin

@Parcelize
data class User(
    val name: String,
    val age: Int
) : Parcelable

@Composable
fun UserScreen() {
    var user by rememberSaveable { 
        mutableStateOf(User("Alice", 25))  // ✅ 自动保存
    }
}

3. 复杂对象 - 自定义 Saver

  • 与 remember 的对比
特性 remember rememberSaveable
重组后保持 ✅ 能 ✅ 能
屏幕旋转后 ❌ 不能 ✅ 能
进程杀死后 ❌ 不能 ✅ 能(系统自动保存 Bundle)
存储位置 内存中的组合树 Bundle + 内存
存储容量 无限制 受 Bundle 大小限制
性能开销 稍大(需要序列化)
  • 应用场景
    "用户填的表单、选的 Tab、展开的项目,都应该用 rememberSaveable"

rememberCoroutineScope

rememberCoroutineScope() 返回一个与当前 Composable 生命周期绑定的协程作用域

rememberUpdatedState

  • 与remember的对比
特性 remember rememberUpdatedState
用途 存储值 获取最新值(在副作用中)
触发重组 ✅ 会 ❌ 不会
更新时机 值变化时 只更新内部引用
典型场景 UI 状态 回调、长时间运行的协程
返回值 可变或只读 只读 State
  • 应用场景
    rememberUpdatedState 不是用来获取最新值,而是用来确保执行的是最新的函数/回调
场景 是否需要 rememberUpdatedState 原因
读取变量值 ❌ 不需要 Kotlin 闭包捕获引用
调用动态函数 ✅ 需要 函数对象本身可能变化
使用 lambda 参数 ✅ 需要 lambda 可能被替换
监听器/回调 ✅ 需要 监听器实现可能变化

derivedStateOf

"复杂计算、组合状态、条件逻辑,需要用 derivedStateOf 来优化性能"


0 条评论

发表回复

您的电子邮箱地址不会被公开。