簡體   English   中英

Lambda function 用作輸入參數導致重組

[英]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()
    }
}

我的問題:

  1. 為什么這個 lamda function 導致重組
  2. 修復它的最佳方法

我對這個問題的理解

從 compose 編譯器報告中我可以看到 B 是一個可跳過的 function 並且輸入 onClick 是穩定的。 起初我雖然是因為 lambda function 在每次重組 A 時都會重新創建,並且它與之前的不同。 而這種差異會導致B的重組。但這不是真的,因為如果我在lambda function內部使用其他東西,比如改變state,它不會導致重組。

我的解決方案

  1. 盡可能使用委托。 像 viewmode::doSomething 或 ::doSomething。 不幸的是,它並不總是可能的。
  2. 使用 lambda function 里面記住:
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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM