记住,当jetpack组合中的值发生变化时,不要重新组合



我正在增加一个值,我想在此基础上改变文本的颜色。当我的值改变时,我的文本颜色不会改变。

PairStateFul

@Composable
fun PairStateFul() {
var selectedIndexOfAvailableItem by remember { mutableStateOf(-1) }
val pairButtonColor = remember {
if (selectedIndexOfAvailableItem != -1) {
Color.Blue
} else {
Color.Yellow
}
}
Column {
PairStateLess(
pairButtonColor,
selectedIndexOfAvailableItem,
onSelectedIndexOfAvailableItem = { selectedIndexOfAvailableItem += it }
)
}
}

PairStateLess

@Composable
fun PairStateLess(pairButtonColor: Color,
selectedIndexOfAvailableItem: Int,
onSelectedIndexOfAvailableItem: (Int) -> Unit,
) {
Text(
"Hello World!",
color = pairButtonColor
)
Button(onClick = {
onSelectedIndexOfAvailableItem(selectedIndexOfAvailableItem)
}) {
Text(text = "item $selectedIndexOfAvailableItem")
}
}

PairStateFulPreview

@Preview(showBackground = true)
@Composable
fun PairStateFulPreview() {
PairStateFul()
}

我知道我的递增计数器逻辑是错误的。我不想解决逻辑问题。我的主要问题是,当selectedIndexOfAvailableItem改变时,我的pairButtonColor也会改变。

在这种情况下,您根本不需要remember- Compose已经永远不会改变pairButtonColor所依赖的任何东西,除非selectedIndexOfAvailableItem改变,所以可以简单地删除remember并写入:

val pairButtonColor =  if (selectedIndexOfAvailableItem != -1) {
Color.Blue
} else {
Color.Yellow
}

但是要理解为什么你的remember不起作用,重要的是要理解remember { }在做什么。当你写

val pairButtonColor = remember {
// ...
}

块中的代码只运行一次,它返回的值被记住(这就是remember的全部意义)。

这就是为什么remember也有一个接受单个密钥或多个密钥的版本:

如果keys的所有值都等于之前的组合,则记住calculation[代码块]返回的值,否则通过调用calculation产生并记住一个新值。

这意味着,如果您希望rememberselectedIndexOfAvailableItem更改时重新运行,那么它需要是您使用的键之一:

val pairButtonColor = remember(selectedIndexOfAvailableItem) {
if (selectedIndexOfAvailableItem != -1) {
Color.Blue
} else {
Color.Yellow
}
}

但是根据关于使用记忆的最佳实践,remember的用法像这样,数据源已经是一个记忆值,主要是为了避免昂贵的计算(即,如果代码块重新运行非常昂贵,pairButtonColor上的remember可能会有所帮助)或依赖于快速变化的记忆值的计算(其中remember+derivedStateOf将有助于提高性能)。

在您的情况下,两者都不应用-if检查是根本不需要remember的东西。

最新更新