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

Jetpack Compose中rememberUpdatedState与mutableStateOf的区别及适用场景

关于rememberUpdatedState的疑问解答

一、它和不带remember的mutableStateOf本质不同

虽然你的示例里var2(不带remember的mutableStateOf)和var3(rememberUpdatedState)看起来值始终同步,但两者底层逻辑完全不一样:

  • var2 = mutableStateOf(derivedVar):每次TextChild重组时,都会创建全新的MutableState实例,初始值是当前重组时的derivedVar。旧实例会被丢弃,每次重组都是新对象。
  • var3 = rememberUpdatedState(derivedVar):它会复用同一个MutableState实例,仅在每次重组时把实例的value更新为最新的derivedVar。实例从第一次重组就被remember保留,后续不会重新创建。

二、核心适用场景:在持久化副作用中获取最新值

rememberUpdatedState的关键作用,是解决副作用闭包捕获旧值的问题。比如使用LaunchedEffect、DisposableEffect这类仅在指定key变化时重启的副作用时,闭包默认会捕获副作用启动时的旧参数值,后续参数更新后闭包也拿不到新值。用rememberUpdatedState包裹参数,就能让闭包里始终拿到最新值。

举个对比示例:

@Composable
fun TextChild(derivedVar: Int) {
    // 情况1:直接用derivedVar,LaunchedEffect启动后无法感知后续参数变化
    LaunchedEffect(Unit) {
        while (true) {
            delay(1000)
            println("直接捕获的derivedVar:$derivedVar") // 永远是第一次传入的值
        }
    }

    // 情况2:用rememberUpdatedState包裹,能拿到最新值
    val latestDerivedVar = rememberUpdatedState(derivedVar)
    LaunchedEffect(Unit) {
        while (true) {
            delay(1000)
            println("最新的derivedVar:${latestDerivedVar.value}") // 参数更新后会打印新值
        }
    }
}

在你原示例里,因为TextChild每次重组都会重新执行整个函数体,所以var2和var3的value看起来一致,但放到不会重组的副作用闭包里,差异会立刻显现——var2每次重组生成新实例,副作用闭包如果捕获旧实例就拿不到新值;而var3的实例始终唯一,value会被更新,闭包里能拿到最新值。

三、原示例三个变量的差异总结

  • var1 by remember { mutableStateOf(derivedVar) }:第一次重组创建并remember住MutableState,后续重组不会重新初始化,value永远是第一次的derivedVar,不会更新。
  • var2 = mutableStateOf(derivedVar):每次重组新建实例,value是当前重组时的derivedVar,但实例是临时的,无法在持久化逻辑中复用。
  • var3 = rememberUpdatedState(derivedVar):复用同一个实例,每次重组更新value为最新的derivedVar,适合在持久化副作用中引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:47:51