https://kotlinlang.org logo
#compose-android
Title
# compose-android
s

Shubham Singh

11/19/2023, 9:25 AM
Hi friends.. while creating a child composable what would be a better approach and why? 1. Passing the value (T) directly to the child composable i.e.
Copy code
@Composable
fun MyComposable(
    value: T, 
    onValueChange: (T) -> Unit,
)  {
    ...
}
Or 2. Passing the state variable (MutableStateT): i.e.
Copy code
@Composable
fun MyComposable(valueState: MutableState<T>) {
    ...
}
Also, are there any performance differences between the two approaches (considering some composables can get pretty complex)?
s

Stylianos Gakis

11/19/2023, 9:58 AM
Don't pass
MutableState<T>
. Either pass
T
or
() -> T
if you need to defer the read. There's been many discussions about this here and in #compose, do a search for them
s

Shubham Singh

11/19/2023, 9:59 AM
Got it Thank you Although I will be trying to search, I'd highly appreciate it if you could provide with some of those chats, that'd save me a lot of time since you probably already know about the keywords we need to make the search with 🙌
c

Chrimaeon

11/19/2023, 10:36 AM
Just search for “state hoisting”
s

Shubham Singh

11/19/2023, 10:38 AM
Gotcha Thank you I found this for now: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1644852692627449?thread_ts=1644783454.508379&amp;cid=CJLTWPH7S But I'm not entirely sure if I'm convinced with the answer, like what exactly is the demerit of using a State object 🤔 Is it the performance? Ease of API use/testing? I'll keep searching for more answers 👍
c

Chrimaeon

11/19/2023, 10:40 AM
It’s about what a composable should know about the parameters it gets in. Keep it simple and concise.
s

Shubham Singh

11/19/2023, 10:42 AM
Understood That makes sense Thanks
s

Stylianos Gakis

11/19/2023, 10:54 AM
Yep that’s the exact thread I was thinking about. Basically
() -> T
is strictly better than
MutableState<T>
, as it allows for the same benefits (deferring reads) while allowing more flexibility, like calling it with a constant value without having to create mutableState first, which is typically useful for previews for example.
s

Shubham Singh

11/19/2023, 11:01 AM
Understood The compose team should mention this point somewhere to guide users a little better Or maybe they have and I've missed reading it?
c

Chrimaeon

11/19/2023, 11:07 AM
the thing is, it’s just a best practice - you can pass whatever you want. It’s an architectural decision that you make for your projects.
s

Shubham Singh

11/19/2023, 11:09 AM
Still, there are a lot of things on the Android Developers website that they explicitly mention is just a best practice and not a rule per-se. I believe they could just add this as just another good-to-read 'Note' on the
Performance Best Practices
page
a

ascii

11/19/2023, 11:21 AM
Copy code
java.lang.IllegalStateException
Reading a state that was created after the snapshot was taken or in a snapshot that has not yet been applied
If you need further motivation, ^ this rare crash went away when a a colleague switched to
() -> T
&
(T) -> Unit
for reads/writes. Our code may have had some other root cause, but that's the thing: using MutableState directly tempts you to use it wherever, however. Bad things usually follow bad practices. For you, the dev, composable functions do not need to know where the data comes from, so try to be as implementation-agnostic as you can.
👍 1
s

Shubham Singh

11/19/2023, 11:28 AM
My thought was that since I am passing down the state object(s) instead of direct values, I am making sure that my Composable function itself doesn't get called over and over again for value updates. It only gets called once, passes down the observable/snapshot/MutableState, only some parts of its content that are observing this state get refreshed on value change and the parent composable never gets called again (or at least gets called lesser than before) hence potentially improving my app's performance and reducing my reliance on the Compose Compiler to make these good performance decisions for me and skipping recompositions as much as possible.
But now that I have got some inputs from you folks, I feel it should be alright if I avoid passing down states The performance should be fairly similar.
s

Stylianos Gakis

11/19/2023, 11:39 AM
It shouldn’t just be be “fairly similar”. It should be the same. Both these two approaches would successfully make your composables not recompose unnecessarily, but only have the recomposition scope which does actually read the state recompose when that state changes. Besides that, you should definitely not make your code spaghetti just for the sake of performance. Especially when you don’t even have a performance problem in the first place 😉
s

Shubham Singh

11/19/2023, 11:40 AM
You're right 😄 thanks for the explanation 🙌
z

zsmb

11/19/2023, 3:06 PM
There's also a direct answer to this in one of the two API guidelines documents for Compose (as well as the answers to many many similar questions) https://github.com/androidx/androidx/blob/androidx-main/compose/docs/compose-component-api-guidelines.md#mutablestatet-as-a-parameter
👏 2
3 Views