android jetpack compose 中的 "remember" 和 "mutableState" 有什么区别?

What is the difference between "remember" and "mutableState" in android jetpack compose?

我是 Jetpack Compose 的新手,正在尝试了解 remembermutableStateOf

之间的区别


换句话说,这条线之间的差异

val text = remember{ mutableStateOf("") }

还有这个

val text = remember{ "" }

还有这个

val text = mutableStateOf("")

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

根据文档:“在缓存昂贵的 UI 操作(例如计算文本格式)时,您可以存储不可变值。记住的值与称为 remember 的可组合项一起存储在 Composition 中。” Source

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

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

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

val state: Int = remember { 1 }

上面代码中的state是不可变的。如果您想更改该状态并更新 UI,您可以使用 MutableStateCompose 将观察任何 reads/writes 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) }

关于你问题的最后一部分:

val text = mutableStateOf("")

如果您执行上述操作,您只是创建了一个 MutableState 对象而没有记住它。

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

据我了解。

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 个实例

如果 remember 与字段一起使用,它的值将在重组中保持不变。

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

mutableStateOf(): 它是一个可观察对象,当底层值发生变化并更新 UI 时观察值。就像我们使用 liveDatastateFlows 但 LiveData 也有生命周期机制,几乎与 StateFlows 一样。

记住{}:它在整个重组过程中保留数据。
什么是重组?当状态发生变化时,保存该值的可组合项会重新组合自身以提供更新后的值。
例如: 我们有一个观察值的 textView(可组合),现在是 1。我们按下按钮并增加 2 的值。当值从 1 变为 2 时,textView(可组合)重新创建(重组)本身并向我们显示更新后的值 2 ,这称为重组。

当我们使用这个时:val text = remember{ mutableStateOf("") } 这意味着我们不仅要观察数据,还要在重组过程中持久化数据。