You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose:remember包裹derivedStateOf是否存在行为差异?

为什么Jetpack Compose中derivedStateOf需要配合remember使用?

在Jetpack Compose的常规示例里,derivedStateOf总是被包裹在remember中,但从表面重组次数看,两种写法似乎没区别:

val foo = remember { derivedStateOf { someState } }

和

val foo = derivedStateOf { someState }

但二者的核心差异在于**derivedStateOf实例的复用性**,结合你给出的示例详细分析如下:

无remember的情况

代码示例:

@Composable
fun Test() {
    var count by remember {
        mutableStateOf(0)
    }

    val moreThanOne = derivedStateOf {
        Log.d("foo", "Calculate")
        count > 1
    }

    Log.d("foo", "Read")
    moreThanOne.value

    Button(
        onClick = {
            Log.d("foo", "Clicked")
            count += 1
        }
    ) {
        Text(text = "Increment")
    }
}

点击按钮两次后的日志:

Read
Calculate
Clicked
Calculate
Clicked
Calculate
Read
Calculate

有remember的情况

修改后的代码:

@Composable
fun Test() {
    var count by remember {
        mutableStateOf(0)
    }

    val moreThanOne = remember {
        derivedStateOf {
            Log.d("foo", "Calculate")
            count > 1
        }
    }

    Log.d("foo", "Read")
    moreThanOne.value

    Button(
        onClick = {
            Log.d("foo", "Clicked")
            count += 1
        }
    ) {
        Text(text = "Increment")
    }
}

点击按钮两次后的日志:

Read
Calculate
Clicked
Calculate
Clicked
Calculate
Read

差异原因解析

  1. 无remember的逻辑:
    每次Test重组时,都会创建一个全新的derivedStateOf实例。这个新实例没有之前的计算缓存,所以读取moreThanOne.value时,必须重新执行计算块(也就是日志最后多出来的那次Calculate)。

  2. 有remember的逻辑:
    remember会在首次组合时创建derivedStateOf实例,并在后续重组中复用这个实例。derivedStateOf内部会缓存计算结果,只有当它依赖的count变化时,才会重新执行计算块。最后重组读取moreThanOne.value时,缓存已经是最新的,所以不会触发额外计算。

总结

  • remember的核心作用是在重组时保留对象实例,避免重复创建。
  • derivedStateOf的缓存优化只有在复用同一个实例时才能生效,否则每次重组都会带来不必要的重复计算,增加性能开销。
  • 即使表面重组次数相同,无remember的写法会导致更多计算逻辑执行,复杂场景下性能差异会更明显。

内容的提问来源于stack exchange,提问作者Kuno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:35:21