Должен ли я использовать значение напрямую или отложить композицию, передав лямбда в Compose Jetpack

Я изо всех сил пытаюсь понять, следует ли мне передать значение составной функции или лямбда. Давайте посмотрим на мой пример. Пожалуйста, пропустите LaunchedEffect, это просто для моделирования изменяемых данных.

Мои вопросы: в этом случае я должен использовать ComposableTextDirect или ComposableTextLambda и почему?

@Composable
fun ComposableContainer() {
    val coroutineScope = rememberCoroutineScope()
    var aTextThatCanBeChangedBySomethingElse by remember {
        mutableStateOf("")
    }
    LaunchedEffect(key1 = Unit) {
        coroutineScope.launch(Dispatchers.IO) {
            while (isActive) {
                delay(1_000L)
                aTextThatCanBeChangedBySomethingElse = Date().toString()
            }
        }
    }
    Column {
        ComposableTextDirect(text = aTextThatCanBeChangedBySomethingElse)
        ComposableTextLambda {
            aTextThatCanBeChangedBySomethingElse
        }
    }

}

@Composable
fun ComposableTextDirect(text: String) {
    Text(text = text)
}

@Composable
fun ComposableTextLambda(provider: () -> String) {
    Text(text = provider())
}

Я попробовал приведенный выше код, и он работает хорошо и такой же, как и другие.

Я не могу заметить каких-либо различий в поведении, если не учитывать дополнительный функциональный объект, который генерируется каждый раз, когда вы вызываете лямбда-версию.

Tenfour04 31.03.2023 05:57

@ Tenfour04 Мне просто интересно, передать ли значение напрямую или передать значение лямбда, чтобы избежать перекомпоновки.

fshdn19 31.03.2023 06:15

использование лямбда является одним из предложений по повышению производительности, но в большинстве случаев это избыточно и только усложняет ваш код, поэтому используйте его, если у вас действительно есть проблемы с производительностью из-за частых обновлений - например. с помощью анимации.

Phil Dukhov 31.03.2023 08:16
1
3
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Так что, в принципе, как вы это написали, это не будет иметь никакого значения, но обратите внимание на одну вещь. Если вы измените свой код следующим образом:

@Composable
fun ComposableContainer() {
    val coroutineScope = rememberCoroutineScope()
    var aTextThatCanBeChangedBySomethingElse = remember {
        mutableStateOf("")
    }
    LaunchedEffect(key1 = Unit) {
        coroutineScope.launch(Dispatchers.IO) {
            while (isActive) {
                delay(1_000L)
                aTextThatCanBeChangedBySomethingElse.value = Date().toString()
            }
        }
    }
    Column {
        Text(text = "Test")
//        ComposableTextDirect(text = aTextThatCanBeChangedBySomethingElse.value)
        ComposableTextLambda {
            aTextThatCanBeChangedBySomethingElse.value
        }
    }

}

Будет разница. Просто посмотрите на инспектор компоновки и рекомпозиции. Текст будет перекомпонован несколько раз, если вы используете

        ComposableTextDirect(text = aTextThatCanBeChangedBySomethingElse.value)

и он не будет перекомпонован в случае, если вы используете

  ComposableTextLambda {
            aTextThatCanBeChangedBySomethingElse.value
        }

Причина этого в том, что каждый раз, когда вы наблюдаете изменяемое состояние в каком-либо составном объекте, вы будете перекомпоновывать его при каждом изменении значения.

Короче говоря, используйте изменяемое состояние на самом низком уровне, чтобы избежать рекомпозиций.

Спасибо за ваш очень подробный ответ. То есть вы имеете в виду, что если возможно, я должен использовать ComposableTextLambda, чтобы уменьшить рекомпозицию? Но я думаю, что это сделает код более сложным. Я думаю, что ComposableTextLambda все еще получают рекомпозицию, когда текст изменился. Но с лямбдой это уменьшает объем композиции, верно?

fshdn19 03.04.2023 03:46

Да, в основном в этом случае это было бы сложнее, поэтому вам было бы проще перемещать свои изменяемые данные внутри ComposableTextLambda. Бывают, конечно, времена, когда это будет невозможно, и это тоже нормально, но перекомпоновки будут происходить чаще на верхних уровнях.

Милош Којадиновић 03.04.2023 09:53

Другие вопросы по теме