【问题标题】:What is the difference between "remember" and "mutableState" in android jetpack compose?android jetpack compose中的“remember”和“mutableState”有什么区别?
【发布时间】:2021-05-16 01:42:53
【问题描述】:

我是 jetpack compose 的新手,并试图了解 remembermutableStateOf 之间的区别


换句话说,这条线之间的尊重

val text = remember{ mutableStateOf("") }

还有这个

val text = remember{ "" }

还有这个

val text = mutableStateOf("")

【问题讨论】:

    标签: android android-jetpack android-jetpack-compose


    【解决方案1】:

    remember 是一个可组合的函数,可用于缓存昂贵的操作。您可以将其视为可组合的本地缓存。

    val state: Int = remember { 1 }
    

    上述代码中的state 是不可变的。如果您想更改该状态并更新 UI,您可以使用MutableStateCompose 观察对MutableState 对象的任何读取和写入,并触发recomposition 以更新 UI。

    val state: MutableState<Int> = remember { mutableStateOf(1) }
    
    Text(
       modifier = Modifier.clickable { state.value += 1 },
       text = "${state.value}",
     )
    

    另一个变体(在alpha12 中添加)称为rememberSaveable,类似于remember,但存储的值可以在进程死亡或配置更改后继续存在。

    val state: MutableState<Int> = rememberSaveable { mutableStateOf(1) }
    

    注意:您还可以使用属性委托作为语法糖来解开MutableState

    var state: Int by remember { mutableStateOf(1) }
    

    关于您问题的最后一部分,如果您在可组合物中执行如下所示的操作,那么您只是在创建一个 MutableState 对象。

    val state: MutableState<Int> = mutableStateOf { 1 }
    

    MutableState 是使用 LiveDataFlow 的替代方法。 Compose 默认情况下不会观察到此对象的任何更改,因此不会发生重组。如果您希望观察更改并缓存状态,请使用remember。如果不需要缓存只想观察,可以使用derivedStateOf。这是sample 的使用方法。

    【讨论】:

    • 您能检查一下问题的编辑吗? @ckunder
    • @AhmedM.Abdalla 我已经更新了我的答案。
    【解决方案2】:

    据我了解。

    remember 只是缓存计算结果在组合之间保留结果实例。任何物体。和MutableState 实例。这就是它有用的原因。

    val text = remember{ "" }
    

    只缓存空字符串。

    val text = mutableStateOf("")
    

    创建MutableStatecompose 观察它的值,但不缓存MutableState 实例,所以它会在下一次重组时重新创建(当然如果重组会发生在这个地方)

    例如:

    val state: MutableState<Int> =  mutableStateOf(1)
    println(state.toString())
    Text(
        modifier = Modifier.clickable { state.value += 1 },
        text = "${state.value}",
    )
    

    文本将始终为 1,因为每次重组都会重新创建 state,并且输出将是:

    MutableState(value=1)@227069120
    MutableState(value=1)@104526071
    MutableState(value=1)@915621104
    MutableState(value=1)@580489706 
    

    remember 缓存 MutableState 对象并在每次重组时保持相同的实例

    val state: MutableState<Int> = remember { mutableStateOf(1) }
    println(state.toString())
    Text(
        modifier = Modifier.clickable { state.value += 1 },
        text = "${state.value}",
    )
    

    按预期工作。

    MutableState(value=2)@1121832406
    MutableState(value=3)@1121832406
    MutableState(value=4)@1121832406
    MutableState(value=5)@1121832406
    

    记住(键)

    val key = remember { 0 }
    var state by remember(key) { mutableStateOf(1) }
    println(state.toString())
    Text(
        modifier = Modifier.clickable { state += 1 },
        text = "${state}",
    )
    

    即使key 没有改变,也像上面的例子一样工作。这是因为在 MutableState 的情况下,缓存的不是值,而是 MutableState 的实例本身带有 value 字段,它会发生变化。

    更改 key 值将重新创建 MutableState 实例

    【讨论】:

    • 这个答案给出了根本原因:重复调用fun时保留状态数据,否则会重复初始化。
    【解决方案3】:

    如果remember 与字段一起使用,则其值将在重新组合中保持不变。

    如果mutableState 与字段一起使用,则只要字段值更改,所有使用该字段的可组合项都将重新组合。

    【讨论】:

      【解决方案4】:

      基本上,在第一个示例中,您存储一个可变值,而在第二个示例中,您存储一个不可变值。

      根据文档:“您可以在缓存昂贵的 UI 操作(例如计算文本格式)时存储不可变值。记住的值存储在组合中,其中包含调用记住的组合。” Source

      有关 mutableStateOf 的更多信息,请参阅文档 link。当您希望在您的值发生变化时重新组合您的 UI 时,您可以使用它。

      【讨论】:

        【解决方案5】:

        remember 关键字可以存储可变或不可变对象。如果你传递 mutableStateOf 来记住,只要该对象的值发生变化,它就会强制重新组合正在读取该值的可组合项。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多