为什么在回调中调用ViewModel时会发生重组? [英] Why recomposition happens when call ViewModel in a callback?

查看:34
本文介绍了为什么在回调中调用ViewModel时会发生重组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我完全搞不懂作曲这个概念。 我有一个代码

@Composable
fun HomeScreen(viewModel: HomeViewModel = getViewModel()) {
    Scaffold {
        val isTimeEnable by viewModel.isTimerEnable.observeAsState()
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center,
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Black),
        ) {
            Switch(
                checked = isTimeEnable ?: false,
                onCheckedChange = {
                    viewModel.setTimerEnable(it)
                },
            )
            Clock(viewModel.timeSelected.value!!) {
                viewModel.setTime(it)
            }
        }
    }
}

@Composable
fun Clock(date: Long, selectTime: (date: Date) -> Unit) {
    NumberClock(Date(date)) {
        val time = SimpleDateFormat("HH:mm", Locale.ROOT).format(it)
        Timber.d("Selected time: time")
        selectTime(it)
    }
}

为什么Clock小工具在我点击开关时重新组合。如果从Clock小部件回调中删除第selectTime(it)行,则不会发生重组。 撰写版本:1.0.2

推荐答案

这是因为在组合方面,您每次都会创建一个新的selectTimelambda,因此需要重新组合。如果将setTime函数作为引用传递,Compose将知道它是同一个函数,因此不需要重新组合:

Clock(viewModel.timeSelected.value!!, viewModel::setTime)

或者,如果您有更复杂的处理程序,您可以remember

Clock(
    date = viewModel.timeSelected.value!!,
    selectTime = remember(viewModel) {
        {
            viewModel.setTimerEnable(it)
        }
    }
)

请注意,您需要将可能更改的所有值作为键传递,因此remember将按需重新计算。


总的来说,重组并不是一件坏事。当然,如果您可以减少它,您应该这样做,但您的代码应该可以很好地工作,即使它被多次重新组合。例如,您不应该在Composable中进行繁重的计算,而应该使用side effects

因此,如果重新组合Clock导致奇怪的UI效果,可能是NumberClock有问题,无法在重新组合后存活。如果是,请将NumberClock代码添加到您的问题中,以获取有关如何改进它的建议。

这篇关于为什么在回调中调用ViewModel时会发生重组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆