请考虑下面的代码片段

fun doSomething(){
}

@Composable
fun A() {
    Column() {
        val counter = remember { mutableStateOf(0) }
        B {
            doSomething()
        }
        Button(onClick = { counter.value += 1 }) {
            Text("Click me 2")
        }
        Text(text = "count: ${counter.value}")
    }
}

@Composable
fun B(onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text("click me")
    }
}

现在,当按下"Click Me 2"按钮时,B Compose函数将被重新组合,尽管它内部的内容没有任何变化.

Clarification:做点什么是为了演示.如果你坚持要有一个实际的例子,你可以考虑下面B的用法:

B{
    coroutinScope.launch{
        bottomSheetState.collapse()
        doSomething()
    }
}

My questions:

  1. 为什么这个Lamda函数会导致重组
  2. 修复它的最好方法

我对这个问题的理解

从Compose编译器报告中,我可以看到B是一个可跳过的函数,并且输入onClick是稳定的.起初我认为这是因为A的每一次重组都会重新创建lambda函数,它与以前的不同.这种差异会导致B的重组,但这不是真的,因为如果我在lambda函数中使用其他东西,比如更改状态,它不会导致重组.

我的解决方案

  1. 如果可能,请使用委托.就像视图模式::做某事或::做某事.不幸的是,这并不总是可能的.
  2. 请记住,在内部使用lambda函数:
val action = remember{
    {
        doSomething()
    }
}
B(action)

看起来很难看=) 3.以上各项的结合.

推荐答案

一般来说,如果您在lambda函数中使用不稳定的属性,则会导致子组合函数不可跳过,因此每次重新组合其父函数时都会重新组合.这不是很容易看到的东西,你需要小心处理.例如,下面的代码将导致B被重组,因为coroutinScope是一个不稳定的属性,我们将其用作lambda函数的间接输入.

fun A(){
    ...
    val coroutinScope = rememberCoroutineScope()
    B{
        coroutineScope.launch {
            doSomething()
        }
    }
}

要绕过这一点,您需要在您的lambda或委派(::操作符)周围使用记住.this video里面有一张关于它的纸条.大约40:05

还有许多其他参数是不稳定的,比如上下文.要弄清楚它们,您需要使用Compose编译器报告.

这里有一个很好的解释:https://multithreaded.stitchfix.com/blog/2022/08/05/jetpack-compose-recomposition/

Android相关问答推荐

在Android Studio Iguana 2023.2.1中,哪里可以找到能量分析器?

如何使禁用状态下的material 3按钮与启用状态下的 colored颜色 相同?

如何让用户与我的应用生成的多个音频文件交互

Jetpack编写Lazy列滑动删除动画不顺利结束

Android Jetpack Compose Material3主题配色方案

Android和Rust,OpenSSL交叉编译在ARM V7上链接失败

Android在NavHost中的LazyColumn中编写约束布局:error - replace()在未放置的项目上调用

Android布局渲染问题

Kotlin为多个控件设置一个侦听器

Android-交叉引用表中的ForeignKey用于什么?

如何判断堆肥是否为空?

Android studio应用判断无法打开离线数据库

Color.Transparent 和 Color.Unspecified 之间的区别

如何仅同步 local_manifest.xml?

Android apk 不工作

如何正确地将图像上传到 Jetpack Compose 中的 LazyList 中的项目?

我的观点在jetpack compose中相互重叠

状态值更改时屏幕未重新组合 - Jetpack Compose

如何在 TextButton 中分隔文本和图标

构成material 3 中的分隔符