喷气背包组合 - 忽略函数参数的重构



我正在检查由高阶组件传递给我的可组合组件的标志值,但返回的值始终是初始值...

这是我的组件:

@Composable
fun Test(enabled: Boolean) {
var expanded by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
if (enabled) expanded = !expanded
println("enabled is $enabled") //always prints the initial value of enabled
}
) {
OutlinedTextField(
value = "value",
onValueChange = { },
modifier = Modifier.fillMaxWidth(),
enabled = enabled,
readOnly = true,
label = { Text("Label") },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
DropdownMenuItem(
onClick = {
expanded = false
},
text = {
Text("Content")
}
)
}
}
}

onExpandedChange中的代码忽略enabled的当前值。

例如,如果我运行下面的代码,我可以看到OutlinedTextField在 2 秒后更改为启用状态,但onExpandedChange将使用初始(旧)值 enabled。

Surface(
color = MaterialTheme.colorScheme.background
) {
var flag by remember { mutableStateOf(false) }
println("flag is $flag")
LaunchedEffect(Unit) {
delay(2000)
flag = !flag
println("flag is now $flag")
}
Test(flag)
}

我做错了什么?

编辑: 如果我这样做,它可以正常工作:

@Composable
fun Test(enabled: Boolean) {
var expanded by remember { mutableStateOf(false) }

var enabledState by remember {
mutableStateOf(enabled)
}
LaunchedEffect(enabled) {
enabledState = enabled
}
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
if (enabledState) expanded = !expanded
}
) {
OutlinedTextField(
value = "value",
onValueChange = { },
modifier = Modifier.fillMaxWidth(),
enabled = enabled,
readOnly = true,
label = { Text("Label") },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
DropdownMenuItem(
onClick = {
expanded = false
},
text = {
Text("Content")
}
)
}
}
}

但是如果我这样做就不起作用:

@Composable
fun Test(enabled: Boolean) {
var expanded by remember { mutableStateOf(false) }

val enabledState by remember(enabled) {
mutableStateOf(enabled)
}
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
if (enabledState) expanded = !expanded
}
) {
OutlinedTextField(
value = "value",
onValueChange = { },
modifier = Modifier.fillMaxWidth(),
enabled = enabled,
readOnly = true,
label = { Text("Label") },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
DropdownMenuItem(
onClick = {
expanded = false
},
text = {
Text("Content")
}
)
}
}
}

我不知道为什么...

重构不会忽略更新的函数参数,而是忽略onExpandedChange的闭包。它保留以前的MutableState实例,即使您通过更改密钥重新实例化remember也是如此。所以你应该做的是更新当前实例的值MutableState而不是

val enabledState = remember(enabled) {
mutableStateOf(enabled)
}

您应该按照布鲁诺的建议使用 rememberUpdateState 或更新值

val enabledState by remember {
mutableStateOf(enabled)
}.apply {
value = enabled
}

这就是rememberUpdatedState实现的内容

记住和记住Jetpack Compose中的更新状态之间的区别?

使用rememberUpdatedState,比如

val currentEnabledState by rememberUpdateState(enabled)

然后在不同的范围内传递currentEnabledState

最新更新