kotlin - 为什么可组合对象看似无状态(唯一传递的参数是函数,而不是状态),但会进行重组

标签 kotlin android-jetpack-compose android-viewmodel kotlin-stateflow compose-recomposition

我通过单击第一个可组合项调用相应的函数来更新 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/

相关文章:

testing - 使用多个 `--tests`

Kotlin:扩展函数的惯用用法 - 将扩展函数放在它扩展的类旁边

android - Kotlin RxJava : Type mismatch, 需要观察者但是 ???成立

android - Jetpack Compose,使用自定义 Lifecycle/ViewModelStore/SavedStateRegistry Owner 时不会触发重组

android-jetpack-compose - 喷气背包中的 textAllCaps 撰写

android-room - 使用 Room 自动持久化双向数据绑定(bind)的更改?

android - 为什么 AdnroidInjector.inject(fragment) 使用已弃用的 android.support.v4.app.Fragment

android - 无法在 Kotlin 中构建注释处理器

Android:compileDebugKotlin 失败并出现 java.lang.ClassCastException

Android ViewModel - 如何强制重新创建某些配置更改