https://kotlinlang.org logo
#compose
Title
# compose
g

galex

06/21/2022, 7:50 AM
What's the best option to run a modifier only if a value is not null? We've created this:
Copy code
inline fun Modifier.optional(
    block: Modifier.() -> Modifier?
) = block() ?: this
And we use it this way:
Copy code
.optional {
    frameColor?.let {
        border(4.dp, it, CircleShape)
    }
}
It there a better way to do this? 🤔
z

Zoltan Demant

06/21/2022, 8:06 AM
I dont know if its better, but this is what Ive been doing.
Copy code
inline fun <T> Modifier.conditional(
    value: T?,
    modifier: (T) -> Modifier
): Modifier {
    return conditional(
        condition = value != null,
        modifier = {
            modifier(checkNotNull(value))
        }
    )
}
Copy code
inline fun Modifier.conditional(
    condition: Boolean,
    modifier: () -> Modifier
): Modifier {
    return when {
        condition -> then(modifier())
        else -> this
    }
}
👀 1
y

yschimke

06/21/2022, 8:21 AM
Is it better if these take
condition: () -> Boolean
and use Modifier.composed? Does that avoid extra work in the compose phase? (I don't know answer but am curious)
🤔 1
g

galex

06/21/2022, 8:31 AM
@Zoltan Demant Thank you so much I didn't know about
checkNotNull
! The only thing I disliked in your solution is that you have to create a new Modifier in the body of your modifier lambda, so I changed it to
Copy code
inline fun <T> Modifier.conditional(
    value: T?,
    modifier: Modifier.(T) -> Modifier
): Modifier {
    return conditional(
        condition = value != null,
        modifier = {
            modifier(checkNotNull(value))
        }
    )
}
inline fun Modifier.conditional(
    condition: Boolean,
    modifier: () -> Modifier
): Modifier {
    return when {
        condition -> then(modifier())
        else -> this
    }
}
So now I can do:
Copy code
Modifier
    .someStuff(...)
    .conditional(frameColor) {
        border(4.dp, it, CircleShape)
}
Thank you that's exactly what I was looking for! :-D
👍 1
z

Zoltan Demant

06/21/2022, 8:35 AM
@yschimke Youve definitely sparked my curiosity, but I dont know the answer to that. What kind of extra work are you referring to? From my usage at least, the condition is always some state variable - and I think what youre getting at is the change of modifier resulting in less recompositions deeper into the hierarchy? @galex Glad to help! I tend to forget that Im in the Modifier extension scope when using it that way, but to each their own! 🙂
❤️ 1
a

Albert Chang

06/21/2022, 9:02 AM
Modifier.composed
isn’t an optimization. It’s actually more expensive than a non-composed modifier. You should only use it when you need to call composable functions or read composition locals. There is even a lint warning when you use it unnecessarily.
y

yschimke

06/21/2022, 9:04 AM
That's good to know. I was thinking about cases where the state is only accessed inside the Modifier function? I thought even in that third case (state reads) it was more efficient to use composed. I wasn't aware that it's expensive, it seems very widely used by framework.
Reading up on docs, it seems to be focused on stateful implementations, not avoiding compositions. TIL
6 Views