[英]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.