【问题标题】:Difference between remember and rememberUpdatedState in Jetpack Compose?Jetpack Compose 中的 remember 和 rememberUpdatedState 的区别?
【发布时间】:2021-09-07 08:45:13
【问题描述】:

我很困惑,谁能解释一下:

val variable by remember { mutableStateOf() }

val variable by rememberUpdatedState()

当我查看rememberUpdatedStates的源代码时,我实际上看到了:remember { mutableStateOf() }

@Composable
fun <T> rememberUpdatedState(newValue: T): State<T> = remember {
    mutableStateOf(newValue)
}.apply { value = newValue }

【问题讨论】:

标签: android kotlin android-jetpack-compose


【解决方案1】:

rememberrememberUpdatedStates的区别是:

记住

记住计算产生的值。计算只会在作文期间进行评估。重新组合将始终返回组合产生的值。

当您使用 remember 时,每次连续调用 recomposition 只会返回最初在第一次调用 remember 时计算的相同值。您可以将此视为只读状态,您无法在未来参考时更新,而重新计算将参考初始评估。


记住更新状态

记住一个 mutableStateOf 并在每次重新组合 rememberUpdatedState 调用时将其值更新为 newValue。

rememberUpdatedState 应在组合期间计算的参数或值被长期存在的 lambda 或对象表达式引用时使用。重组将在不重新创建长期存在的 lambda 或对象的情况下更新结果状态,允许该对象持续存在而无需取消和重新订阅,或重新启动可能很昂贵或重新创建和重新启动的长期操作。

在这里,预计有时您的计算可能需要一段时间,并且计算可能会相当慢。在这种情况下,会为您提供最新值而不是 lambda,它会对每次重组产生影响,以便您可以参考计算产生的最新值。

通过使用此方法,您可以确保每次重组都更新您的 UI,而无需重新创建长期存在的 lambda 或重新启动您在记住方法的 lambda 回调期间可能执行的长期操作。

【讨论】:

    【解决方案2】:

    当你不想做一些繁重的计算/操作时需要记住,而当你的组合被重组时,有时你的操作可能会改变,所以你需要进行计算或更新记住的值才能使用过时的初始计算值。

    fun <T> rememberUpdatedState(newValue: T): State<T> = remember {
        mutableStateOf(newValue)
    }.apply { value = newValue }
    

    rememberUpdatedState 功能与使用remembermutableStatevalue 发生变化时触发重组 相同。

    @Composable
    private fun Calculation(input: Int) {
        val rememberUpdatedStateInput by rememberUpdatedState(input)
        val rememberedInput = remember { input }
    
        Text("updatedInput: $rememberUpdatedStateInput, rememberedInput: $rememberedInput")
    }
    
    var myInput by remember {
        mutableStateOf(0)
    }
    
    OutlinedButton(
        onClick = {
            myInput++
    
        }
    ) {
        Text("Increase $myInput")
    }
    Calculation(input = myInput)
    

    这是一个非常基本的示例,展示了 values 从 remember 和 rememberUpdatedState 的变化

    更实际的例子是 lambdas

    例如,假设您的应用有一个 LandingScreen,它会在一段时间后消失。即使LandingScreen被重构,等待一段时间并通知时间过去的效果也不应该重新启动:

    @Composable
    fun LandingScreen(onTimeout: () -> Unit) {
    
        // This will always refer to the latest onTimeout function that
        // LandingScreen was recomposed with
        val currentOnTimeout by rememberUpdatedState(onTimeout)
    
        // Create an effect that matches the lifecycle of LandingScreen.
        // If LandingScreen recomposes, the delay shouldn't start again.
        LaunchedEffect(true) {
            delay(SplashWaitTimeMillis)
            currentOnTimeout()
        }
    
        /* Landing screen content */
    }
    

    在此示例中,LaunchedEffect 被调用一次,但此 LandingScreen 函数可以重新组合,并且可能需要您更改 onTimeOut,因此使用 rememberUpdatedState 可确保在延迟后调用最新的 onTimeout。

    【讨论】:

      猜你喜欢
      • 2021-05-16
      • 1970-01-01
      • 2022-11-09
      • 1970-01-01
      • 2021-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多