Jetpack Compose中带key的remember()与derivedStateOf()有何区别?
Compose两种状态处理方式的核心区别
二者除了已知的派生状态优化点外,行为并不完全一致,核心差异如下:
- 「对依赖的要求不同」
第一种val result = remember(key1, key2) { computeIt(key1, key2) }对key没有类型要求,任意类型变量都可以作为key,只要Compose判定key发生了变更就会触发重新计算。
第二种val result by remember { derivedStateOf { computeIt(key1, key2) } }要求key1、key2必须是Compose的State类型才能监听到变化,如果是普通变量,computeIt只会在首次初始化时执行一次,后续key1、key2无论怎么修改都不会更新结果。 - 「重新计算的触发逻辑不同」
第一种只要key发生变更,无论计算结果和旧值是否相等,都会立刻执行computeIt,同时触发当前重组作用域更新。如果key是高频变化的变量(比如列表滚动偏移、动画帧数值),会产生大量无效计算和重组。
第二种仅当key1/key2(必须为State)变化后,读取result时才会执行computeIt,且会自动对比新老计算结果,只有结果发生变更时才会触发订阅了result的作用域重组,大幅降低高频依赖场景的性能损耗。 - 「计算时机不同」
第一种的computeIt是重组过程中同步执行的,key变更后重组时立即计算。
第二种的computeIt是懒执行的,只要没有代码读取result,哪怕key1/key2发生多次变更,也不会触发计算。
注意:如果希望第二种写法能感知普通变量
key1/key2的变更,需要给外层remember也加上对应key,即修改为val result by remember(key1, key2) { derivedStateOf { computeIt(key1, key2) } },即便如此依然和第一种写法的行为有上述后两点差异。
内容的提问来源于stack exchange,提问作者Felix D.
相关产品推荐
相关产品推荐

