Jetpack Compose rememberSaveable(mutableStateOf()) 值丢失?2 种方法解决!
2024-03-07 19:14:21
解决 Jetpack Compose 中 rememberSaveable(mutableStateOf()) 的值丢失问题
问题概览
Jetpack Compose 中的 rememberSaveable
函数可用于在设备旋转或导航等配置更改期间保留状态值。然而,对于可变状态对象(如 mutableStateOf()
),值丢失是一个常见问题。
问题原因
mutableStateOf()
返回的可变状态对象允许其值在运行时更改。但 rememberSaveable
仅在首次调用时对状态对象进行快照。因此,如果在配置更改后更新了可变状态对象,快照值将保持不变,导致值丢失。
解决方法
方法 1:使用 rememberUpdatedState()
rememberUpdatedState()
函数可以跟踪可变状态对象的更新。它返回一个新的状态对象,该对象在原始状态对象更新时会更新。
例如:
var span by rememberUpdatedState(newValue = mutableStateOf(0L))
现在,每次更新 span
时,rememberUpdatedState()
都会返回一个新的状态对象,从而解决值丢失问题。
方法 2:使用 rememberSaveable()
另一种方法是使用 rememberSaveable()
函数直接存储可变状态对象。此方法仅在状态对象的值在配置更改后确实需要保留时才推荐使用。
例如:
var span by rememberSaveable { mutableStateOf(0L) }
注意: 使用此方法时,确保将 saveState
和 restoreState
设置为 true
,以在导航时保留和恢复状态。
例子
方法 1:使用 rememberUpdatedState()
@Composable
fun Screen1() {
var span by rememberUpdatedState(newValue = mutableStateOf(0L))
someOP() {
span = 2
}
}
方法 2:使用 rememberSaveable()
@Composable
fun Screen2() {
var span by rememberSaveable { mutableStateOf(0L) }
someOP() {
span = 2
}
}
常见问题解答
1. 为什么 rememberSaveable()
不会自动更新可变状态对象?
因为 rememberSaveable
仅在首次调用时创建状态对象的快照。
2. 什么时候应该使用 rememberUpdatedState()
,什么时候应该使用 rememberSaveable()
?
- 使用
rememberUpdatedState()
,当需要在配置更改后保持可变状态对象的值更新时。 - 使用
rememberSaveable()
,当需要在配置更改后保留可变状态对象的确切值时。
3. rememberSaveable()
和 saveable()
有什么区别?
rememberSaveable()
用于存储状态对象,而 saveable()
用于存储可序列化数据。
4. 如何在导航时保留和恢复 rememberSaveable()
中存储的状态?
通过将 saveState
和 restoreState
设置为 true
。
5. 为什么使用 rememberUpdatedState()
比使用 rememberSaveable()
效率更高?
因为 rememberUpdatedState()
只在原始状态对象更新时创建新的状态对象,而 rememberSaveable()
总是创建新的状态对象。