我通过单击第一个可组合项调用相应的函数来更新 uiState。 第二个可组合项因此而重组,尽管它不采用任何状态参数,只采用另一个函数。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyScetchApplicationTheme {
Screen(MyViewModel())
}
}
}
}
@Composable
fun Screen(myViewModel: MyViewModel) {
val myUiState by myViewModel.uiState.collectAsState()
Column {
MyBox(myViewModel::changeParameter) // when clicking this
MyBox(myViewModel::changeOtherParameter) // that recomposes
MyBox{ } // but that one doesn't
Text("${myUiState.otherParameter}") // and neither does that one
}
}
@Composable
private fun MyBox(function: () -> Unit) {
Box(
modifier = Modifier
.padding(20.dp)
.size(80.dp)
.background(Color.Gray)
.clickable { function() }
)
}
class MyViewModel: ViewModel() {
private var _uiState = MutableStateFlow(MyUiState())
val uiState: StateFlow<MyUiState> = _uiState.asStateFlow()
fun changeParameter() {
_uiState.update { it.copy(parameter = !uiState.value.parameter) }
}
fun changeOtherParameter() {
_uiState.update { it.copy(otherParameter = !uiState.value.otherParameter) }
}
}
data class MyUiState (
val parameter: Boolean = false,
val otherParameter: Boolean = false,
)
没有函数作为参数的相同可组合项不会重组,因此函数会以某种方式触发重组。 _ 为什么会发生这种情况,以及如何在不放弃功能的情况下避免这种重组? 由于大量不必要的重组,我的项目变得缓慢。
最佳答案
将函数参数放入remember
中可防止重新组合:
val onClick = remember {myViewModel.someFunction()}
感谢 @Thracian 在评论中提供的答案(还有一些有用的链接)
关于kotlin - 为什么可组合对象看似无状态(唯一传递的参数是函数,而不是状态),但会进行重组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76963088/