Can I mark my `ViewModel` as `@Stable` ? What wud...
# compose
t
Can I mark my
ViewModel
as
@Stable
? What wud be the conditions to do that? (learning about Compose Stability)
d
@Stable
is usually used on classes that are passed in as state to a composable.
ViewModel
is not meant to be used as state, it is a state holder so I am not sure why you would need to tell compose that it is stable.
t
@Composable
s that are inside my
LazyColumn
has its own
ViewModel
. Since data comes from a
SnapshotStateList
, every time I add a new item to the list causing a recomposition to all the children inside the
LazyColumn
. Structure
Copy code
LazyColumn{
    val myDataSet : SnapshotStateList
    ...
    item(myDataSet){ item ->
        MyItem(item)
    }
}

@Composable
fun MyItem(
    item : Item,
    myViewModel : MyViewModel = createViewModel(item.key)
){
    ...
}
This not happening when I remove
MyViewModel
from the
MyItem
. Since all public properties are exposed via the compose
State
, i was thinking why not declare it as
@Stable
?
d
Have you read the guide to state and state hoisting in the compose documentation?
The you should know that using the
ViewModel
this way is not the proper way to use it.
ViewModel
is recommended to be used at the Screen Level not lower then that.
Data in the
ViewModel
can be observed and passed down to
@Composable
s in the screen.
Copy code
LazyColumn{
    val myDataSet = viewModel.dataSet 
    ...
    items(items = myDataSet) { itemState ->
        MyItem(myItemState = itemState)
    }
}

@Composable
fun MyItem(
    myItemState: MyItemState
){
    ...
}
Assuming your
LazyColumn
is in the screen level
@Composable
message has been deleted
MyItemState
would ideally be an immutable
data class
.
t
Eric I got what you’re saying, but I think there’s a difference between “passing down page viewModel” vs composables having its own
viewModel
. In my case, I want my composable to have its own viewModel to control itself. The composable viewModel will be responsible to define the behaviour of the composable. This is a bit different than the
MVVM
arch we see.
d
In that case you would have to make the
ViewModel
@Stable
and ensure it upholds the contract that
@Stable
implies.
Two instances of
MyViewModel(itemA)
should be structurally equal.
MyViewModel(itemA) == MyViewModel(itemA)
should be
true
That seems like it would be a lot of overhead to maintain.
a
To be clear, there’s no problem in marking state holders as stable. For example,
ScrollState
and
LazyListState
are both stable state holders. I recommend that you start with compose compiler metrics and see why it’s not inferred as stable.
Also note that
MyViewModel(itemA) == MyViewModel(itemA)
is not necessary for it to be stable.
t
@Albert Chang
…with compose compiler metrics and see why it’s not inferred as stable.
Copy code
unstable viewModel: MyViewModel? = @dynamic createViewModel(..)
Yes I did that, and its happening because
viewModel
marked as unstable
a
Yeah and what you should do is checking why
MyViewModel
is marked as unstable in classes.txt.
493 Views