Hey folks! A simple question regarding `@Stable` &...
# compose
r
Hey folks! A simple question regarding
@Stable
&
ViewModel
(Ah, here we go again…) I’ve read in some articles and discussions that we should not annotate ViewModel with
@Stable
, but never read what are the implications of annotating it, aside from “_Technically this is not correct and can cause some issues_”, which in my own experience I never had any issue, although every time I tried it I ended up not adding it because it didn’t felt correct based on the recommendations. So here’s the question: Is it ok to annotate
@Stable
to the ViewModel? And if not what are the main cons of annotating it? Maybe there’s an article or an already discussed thread regarding this topic? If so, feel free to share about it Thank you 🙇
c
By adding the
@Stable
you are saying that the class is stable but there is no guarantee of this. So you are relying that there are no bugs, which is already a risk you would be assuming. The ViewModel should hold your logic for displaying the UI, which should not be conflated with the actual data that represents that same UI. That is why is it instead recommended to emit an inmutable data, that way smart recomposition can work effectively.
Additinally,
@Stable
is a whole contract that you need to ensure you meet. You "can" ensure your VM is compliant, but why risk this when you can remove the VM from the composition and just observe inmutable data?
r
The ViewModel should hold your logic for displaying the UI, which should not be conflated with the actual data that represents that same UI.
Could you extend a bit on this? When is it considered that ViewModel is conflated with the UI data? Maybe when ViewModel it’s passed down to the inner composables along some UI data?
You “can” ensure your VM is compliant, but why risk this when you can remove the VM from the composition and just observe inmutable data
Yeah basically, hoisting the state so there’s no need to add that
@Stable
annotation and risk it
c
You composable functions are the UI layer of your app, so if you pass the VM into this function, you are PULLING data out of the ViewModel. This creates a dependency from your UI to your VM. Instead, you want to decouple your UI layer(be it compose, xml, etc) from your ViewModel and just PUSH data from your VM. Then you UI layer can just observe this data.
Bad:
Copy code
@Composable
fun DrawImage(viewModel: ViewModel) {
    Image(viewModel.imageUrl)
}
Correct
Copy code
@Composable
fun DrawImage(imageUrl: String) {
    Image(imageUrl)
}

val imageUrl = viewModel.uistate.observeAsState()

DrawImage(imageUrl)
r
Yep that’s clear, thank you!