jetpack compose 副作用 derivedStateOf

📅 2026/8/15 12:47:03
jetpack compose 副作用 derivedStateOf
derivedStateOf 是 Compose 里把多个 State 计算成一个新 State 的派生状态中枢。它帮你做两件事依赖追踪 结果去重的防抖缓存。标准写法val foo by remember { derivedStateOf { /* 计算 */ } }返回值是 State读取用 .value 或在 composable 中直接解引用。lambda 内读到的所有 State 自动成为依赖基于 Snapshot 读取追踪无需手动声明。指定比较策略equality policy控制「结果是否算变了」的判定方式直接影响是否通知读取者// 默认结构相等即内容相同就不通知 val d1 derivedStateOf(value { ... }) // 或 derivedStateOf { ... } // 引用相等同一对象才算变 import androidx.compose.runtime.structuralEqualityPolicy //默认结果 ! 旧值 import androidx.compose.runtime.referentialEqualityPolicy // 结果引用变了 import androidx.compose.runtime.neverEqualPolicy // 依赖一变就通知 val d2 derivedStateOf( policy referentialEqualityPolicy ) { myState.value.filter { it.active } } val d3 derivedStateOf( policy neverEqualPolicy // 每次依赖变化都通知哪怕结果没变 ) { counter.value % 2 }派生 StateFlow 风格的链式转换val items mutableStateListOfItem() val activeCount derivedStateOf { items.count { it.isActive } } val hasActive by remember { derivedStateOf { activeCount.value 0 } } // 派生再派生derivedStateOf 可以读另一个 derivedStateOf 的结果依赖会自动级联。配合 snapshotFlow 把派生 State 转成 Flowval listState rememberLazyListState() val showFabState remember { derivedStateOf { listState.firstVisibleItemIndex 0 } } LaunchedEffect(Unit) { snapshotFlow { showFabState.value } // 只在布尔翻转时发射 .distinctUntilChanged() .collect { show - analytics.log(fab_visible, show) } }snapshotFlow derivedStateOf 是做「状态变化副作用」的黄金组合依赖频繁抖动但派生值只偶尔翻转副作用只在这些翻转点触发。依赖可变参数时用 keyComposable fun FilteredList(items: ListString, keyword: String) { val matched by remember(keyword) { // keyword 变 → 重建 derivedStateOf derivedStateOf { items.filter { it.contains(keyword) } } } LazyColumn { items(matched) { ... } } }derivedStateOf 它能响应变化全靠 read observer apply observer 这套不依赖重组的感知机制。read observer读时收集依赖作用让读取这个动作留下痕迹建立谁依赖谁的关系。1、触发点State.value 被读取的瞬间2、干的事把被读的 State塞进当前观察者的依赖集合3、价值声明式依赖——你只管在 block 里读 State系统自动知道你依赖了什么不需要手写 addDependency(state)、不需要维护依赖列表apply observer写时通知变化作用让写入这个动作广播出去告诉所有监听者我变了。1、触发点State.value 被写入并 apply 的瞬间2、干的事把本次被修改的 State 集合分发给所有注册的监听者3、价值全局变化通知——一次注册之后任意位置的 State 写入都会通知不需要每个 State 单独发信号、不需要轮询组合起来还带来一个性能价值精确性。1、read observer 让每个 API 只追踪自己 lambda 里读到的那几个 State不波及无关 State2、apply observer 让通知只发给真正依赖该 State 的监听者结果是一次 State 写入只有真正依赖它的代码被唤醒其他无关代码完全不动。这是 Compose 能做到细粒度重组的根基——没有这套机制任何 State 变化都会引发全局重算Compose 就退化成每次状态变都重建整棵 UI 树了。