[英]When recomposition happens exactly? with changing the state or also with changing the input
[英]Lambda function used as input argument causes recomposition
考虑下面的片段
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")
}
}
现在当按下“点击我 2”按钮时,B compose function 将被重新组合,尽管它里面没有任何改变。
说明: doSomething 用于演示目的。 如果你坚持要有一个实际的例子,你可以考虑下面 B 的用法:
B{
coroutinScope.launch{
bottomSheetState.collapse()
doSomething()
}
}
从 compose 编译器报告中我可以看到 B 是一个可跳过的 function 并且输入 onClick 是稳定的。 起初我虽然是因为 lambda function 在每次重组 A 时都会重新创建,并且它与之前的不同。 而这种差异会导致B的重组。但这不是真的,因为如果我在lambda function内部使用其他东西,比如改变state,它不会导致重组。
val action = remember{
{
doSomething()
}
}
B(action)
看起来很难看 =) 3- 以上的组合。
当您点击Button
“Click me 2”时, A
可组合项会因为Text(text = "count: ${counter.value}")
而重新组合。 发生这种情况是因为它重组了正在读取可以更改的值的 scope。
如果您使用的是:
B {
Log.i("TAG","xxxx")
}
单击Button
“Click me 2”不会重新组合 B 可组合项。
如果您正在使用
B{
coroutinScope.launch{
Log.i("TAG","xxxx")
}
}
B 可组合项被重组。
当读取 State 时,它会触发最近的 scope 中的重组。而 scope 是未标记内联并返回 Unit 的 function。
要使用coroutinScope
,您必须使用rememberCoroutineScope
,它是一个可组合的内联 function。 inline
可组合函数的主体被简单地复制到它们的调用站点,这些函数没有自己的重组范围。
为避免它,您可以使用:
B {
Log.i("TAG","xxxx")
}
和
@Composable
fun B(onClick: () -> Unit) {
val scope = rememberCoroutineScope()
Button(
onClick = {
scope.launch {
onClick()
}
}
) {
Text(
"click me ",
)
}
}
来源和学分:
您可以使用第 2 篇博文中描述的LogCompositions
可组合项来检查代码中的重组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.